Skip to content

fix(cosh): report API errors in all output formats, not only text#801

Open
jfeng18 wants to merge 1 commit into
alibaba:mainfrom
jfeng18:fix/cosh-silent-error
Open

fix(cosh): report API errors in all output formats, not only text#801
jfeng18 wants to merge 1 commit into
alibaba:mainfrom
jfeng18:fix/cosh-silent-error

Conversation

@jfeng18

@jfeng18 jfeng18 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

What

In non-interactive mode (cosh -p), API error events (401, 429, etc.) were silently swallowed in JSON and STREAM_JSON output formats — isError: false, exit 0, empty stderr. Programmatic callers had zero indication of failure.

Root Cause

nonInteractiveCli.ts:284 gated error detection on outputFormat === OutputFormat.TEXT. In JSON/STREAM_JSON modes, the GeminiEventType.Error event was consumed by adapter.processEvent() as normal text content, the loop finished normally, and emitResult({isError: false}) was called.

Fix

Remove the outputFormat === OutputFormat.TEXT && condition (one line). Error events now throw in all output formats. The existing catch block already correctly calls adapter.emitResult({isError: true, errorMessage}) for all formats — it just was never reached in JSON/STREAM_JSON mode.

TEXT mode behavior is unchanged (still writes to stderr + exit 1, as before).

Testing

  • ✅ 30 existing tests pass (TEXT mode behavior unchanged)
  • ✅ 2 new discriminating tests added (JSON + STREAM_JSON): verify error propagates + stderr receives message
  • ✅ prettier + eslint clean
  • ✅ 6-agent adversarial review: 5 findings → 0 confirmed (all refuted)

Impact

Mode Before After
TEXT stderr + exit 1 unchanged
JSON stderr empty, isError: false, exit 0 stderr + isError: true, exit 1
STREAM_JSON stderr empty, isError: false, exit 0 stderr + isError: true, exit 1

🤖 Generated with Claude Code

@github-actions github-actions Bot added the component:cosh src/copilot-shell/ label Jun 9, 2026
In non-interactive mode (`cosh -p`), API error events (401, 429, etc.)
were only detected and reported when `outputFormat === OutputFormat.TEXT`.
In JSON and STREAM_JSON modes the error was silently consumed as normal
text content, emitted with `isError: false`, and the process exited 0 —
giving programmatic callers zero indication of failure.

Remove the TEXT-mode guard so error events throw in all output formats.
The existing catch block already correctly calls `adapter.emitResult({
isError: true, errorMessage })` for all formats, so the fix is a single
condition removal.

Adds two discriminating tests (JSON + STREAM_JSON) that verify:
- The error propagates (throw)
- stderr receives the error message (not silently swallowed)

Existing 28 tests continue to pass (TEXT mode behavior unchanged).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jfeng18 jfeng18 force-pushed the fix/cosh-silent-error branch from dd7684e to 5016ab5 Compare June 10, 2026 03:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component:cosh src/copilot-shell/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant