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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes specify workflow run / specify workflow resume behavior under --json by ensuring human-readable error messages are emitted on stderr, preserving stdout for machine-parseable JSON (or empty output on early failure paths).

Changes:

  • Added _error_console(json_output) and routed workflow command error/validation output through it so --json keeps stdout clean.
  • Updated shared _parse_input_values to support json_output and send invalid --input errors to stderr when needed.
  • Added tests asserting validation and input-parse failures do not corrupt stdout under --json and instead appear on stderr.
Show a summary per file
File Description
src/specify_cli/workflows/_commands.py Routes workflow run/resume + shared input parsing error output to stderr when --json is set.
tests/test_workflow_run_without_project.py Adds CLI tests verifying JSON stdout is not corrupted by error text under --json.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Low

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.

3 participants