Skip to content

--json output mode is guessed via naive argv scanning, allowing prose+JSON to both land on stdout #139

Description

@codeforester

Summary

Before Click parses arguments, run_app() decides whether to buffer stdout for JSON-envelope wrapping using a naive scan for the literal token --json in argv — which diverges from Click's actual parse result.

Details

  • lib/python/base_cli/app.py:2971 (_json_requested) just checks whether a literal "--json" token appears anywhere in args, consumed at :2859 and :2872.
  • The correct value is only known later, via _capture_standard_options (:306).
  • This diverges from Click's real parsing whenever --json is set through anything other than an exact literal token: a Click default_map (a standard Click feature), or a combined short-flag form like -xj (meaning -x -j, standard Click flag-combining). Both were reproduced directly.
  • The same heuristic-scanning weakness also exists in _leading_output_flags/_lifecycle_flag_declarations (:3121/:3089) for early debug/quiet detection — lower impact there since it only affects diagnostic verbosity before real option parsing completes.

Impact

When JSON is actually requested via default_map or a combined short flag, the command's own print() output goes to raw stdout (never captured) while run_app() still appends a JSON envelope afterward — producing stdout that is prose followed by JSON. This directly violates the documented contract in docs/json-contracts.md ("exactly one success or error envelope on stdout... cannot introduce prose... as a second stdout record") and breaks any automation parsing stdout as JSON.

Suggested fix

Don't pre-decide based on raw argv; always capture stdout into a buffer for commands whose LifecycleOptions.json is configured (the cost is negligible), and make the final "wrap or not" decision solely from the Click-parsed value already captured in _capture_standard_options.

Metadata

Metadata

Assignees

Labels

bugSomething is not working

Type

No type

Projects

Status
Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions