Skip to content

fix(workflows): route run/resume errors to stderr under --json#3352

Open
jawwad-ali wants to merge 1 commit into
github:mainfrom
jawwad-ali:fix/workflow-json-errors-stderr
Open

fix(workflows): route run/resume errors to stderr under --json#3352
jawwad-ali wants to merge 1 commit into
github:mainfrom
jawwad-ali:fix/workflow-json-errors-stderr

Conversation

@jawwad-ali

Copy link
Copy Markdown
Contributor

Description

specify workflow run/resume --json is contracted to emit a single JSON object on stdout (the module already goes to great lengths for this — see _emit_workflow_json and _stdout_to_stderr_when, which dup2-redirects step output to stderr during execution). But the command's own error paths use console.print, which writes to stdout even under --json:

except FileNotFoundError:
    console.print(f"[red]Error:[/red] Workflow not found: {source}")   # -> stdout
...
console.print("[red]Workflow validation failed:[/red]")               # -> stdout

So a not-found / invalid / validation-failed / failed run — and the shared _parse_input_values invalid-input error — all corrupt the JSON stream a caller is trying to parse.

Fix

Route those error messages through err_console when --json is set (a no-op in normal text mode, where they stay on the regular console). This mirrors the stderr-only error routing already used by specify bundle (_fail) and by err_console elsewhere in this same module. Covers both workflow run and workflow resume plus the shared input parser.

Testing

New TestWorkflowRunJsonErrorStream (CliRunner separates stdout/stderr in this repo's Click):

  • validation-failure under --json: "validation failed" is not on stdout and is on stderr;
  • invalid --input under --json: "Invalid input format" is not on stdout and is on stderr.

Both fail-before / pass-after (verified by source-stash). uvx ruff check clean.

AI Disclosure

  • I did use AI assistance (describe below)

Found and fixed with Claude Code (Claude Fable 5) under my direction. AI spotted that the error paths bypassed the module's own stdout-cleanliness machinery; I confirmed the stream corruption, verified fail-before/pass-after, and reviewed the diff.

workflow run/resume --json is contracted to emit a single JSON object on
stdout, but every error path (workflow-not-found, invalid workflow,
validation failure, execute/resume failure, and the shared
_parse_input_values invalid-input error) used console.print, landing the
human error text on stdout and corrupting the machine-readable stream.
Route those messages through err_console when --json is set (a no-op for
normal text mode), mirroring the stderr-only error routing already used
by 'specify bundle' (_fail) and err_console elsewhere in this module.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jawwad-ali jawwad-ali requested a review from mnriem as a code owner July 5, 2026 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant