Skip to content

Structured data passing for bash steps (JSON-safe variables) #54

@ameet

Description

@ameet

Problem

Passing structured data (JSON objects/arrays) from code steps to bash steps is unsafe and requires a 2-step workaround pattern.

Current workaround (102 instances in our codebase)

Every time a bash step needs a JSON payload, we:

  1. file-write step: Write JSON to a temp file (/tmp/payload-{uuid}.json)
  2. bash step: curl -d @/tmp/payload-{uuid}.json ...

This exists because Handlebars interpolation inside quoted bash strings breaks when the JSON contains quotes, newlines, or special characters. bash_step_regression.py (related: #50) enforces that no flow directly interpolates JSON templates inside quoted strings.

Example of the fragile pattern we're avoiding:

{
  "type": "bash",
  "bash": {
    "command": "curl -d '{{$.steps.buildConfig.output.configJson}}' http://server/endpoint"
  }
}

If configJson contains a single quote, the command breaks. If it contains a newline, the command breaks.

Proposed solution — environment variable injection with type awareness

{
  "type": "bash",
  "bash": {
    "command": "curl -X POST $ENDPOINT -H 'Content-Type: application/json' -d @$PAYLOAD_FILE",
    "env": {
      "ENDPOINT": "{{$.steps.loadConfig.output.SERVER_URL}}/api/process",
      "PAYLOAD_FILE": {
        "json": "{{$.steps.buildConfig.output}}"
      }
    }
  }
}

When env contains a { "json": "..." } value, the CLI:

  1. Serializes the value to JSON
  2. Writes it to a temp file
  3. Substitutes the env var with the temp file path
  4. Cleans up after step completion

For simpler cases (string values that need shell-safe escaping):

{
  "env": {
    "COMPANY_NAME": { "shell": "{{$.steps.data.output.name}}" }
  }
}

Impact

Relationship to existing issues

This extends #50 (unsafe Handlebars in bash). #50 identified the problem; this proposes a concrete mechanism. The printf '%s' workaround from #50 handles simple strings but not structured JSON payloads, which is the more common case.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions