Skip to content

fix: surface real Cerebras request errors instead of a generic fallback#139

Merged
Desperado merged 2 commits into
mainfrom
Desperado/fix-cerebras-backend-error
Jul 11, 2026
Merged

fix: surface real Cerebras request errors instead of a generic fallback#139
Desperado merged 2 commits into
mainfrom
Desperado/fix-cerebras-backend-error

Conversation

@Desperado

Copy link
Copy Markdown
Contributor

Summary

  • The Cerebras backend's error path silently swallowed the actual failure reason. In RunCerebrasAgent (internal/agent/cerebras_agent.go), cancel() was called unconditionally right after every Chat() call for cleanup. But the very next line checked ctx.Err() != nil to detect a genuine user-initiated interrupt (Ctrl-C via Agent.CancelCurrent) — since cancel() had just run, ctx.Err() was always non-nil at that point, so every real failure (bad model, auth error, malformed request, network issue, etc.) took the silent "interrupted" branch and returned false with zero diagnostic output. The caller then only ever saw the generic top-level fallback: cerebras backend request failed.
  • Fix: capture ctx.Err() before the cleanup cancel() call, so the interrupt check reflects whether the context was actually canceled externally during the request, not by our own post-hoc cleanup.

Test plan

  • Added TestRunCerebrasAgentSurfacesRequestErrorDetail, which spins up an httptest server returning HTTP 400 and asserts the detailed error message is printed. Confirmed it fails on the old code and passes with the fix.
  • Reproduced locally end-to-end with a local fake Cerebras-compatible server (both a 400-error case and the happy-path case) via qmax-code --backend cerebras -p "hey".
  • go build ./... and go test ./... pass.

cancel() ran unconditionally right after every Chat() call, so ctx.Err()
was always non-nil by the time the interrupt check ran — every real
failure (bad request, auth error, network issue) was misclassified as
"interrupted" and the detailed term.PrintError message never printed.
Users only ever saw "cerebras backend request failed" with no reason.
@sigilix

sigilix Bot commented Jul 11, 2026

Copy link
Copy Markdown

Sigilix Overview

Effort: 2/5 (small)

Quality gates

  • ✅ PR title follows convention
  • ✅ PR description is complete
  • ℹ️ PR is linked to an issue — No Closes #N / Closes SIG-N keyword found in PR body or commit messages.

Summary — latest push

Fixes a bug in RunCerebrasAgent where an unconditional cleanup cancel() call caused ctx.Err() to always be non-nil, silently swallowing all real request errors into a generic "interrupted" fallback. The fix captures ctx.Err() before the cleanup cancel so genuine user interrupts are still detected while actual API failures now surface their detailed error messages. A new httptest-based regression test validates the detailed error is printed, though the test's captureStdout helper relies on patching the process-global os.Stdout which is a noted fragility.

Important files

File Score Notes Next step
internal/agent/cerebras_agent_test.go 4/5 Adds a regression test ensuring Cerebras request failures surface their actual error message rather than a generic fallback. Refactor captureStdout to inject an io.Writer into the Terminal or CerebrasClient rather than patching the process-global os.Stdout, which is fragile under parallel test execution.
internal/agent/cerebras_agent.go 4/5 Moves the ctx.Err() check before the cancel() cleanup call to prevent real request errors from being misclassified as user interrupts. Add a targeted unit test for the true user-interrupt path (where Agent.CancelCurrent is called mid-request) to guarantee it still returns the silent false as intended.

Confidence: 4/5

The core logic fix is a minimal, high-impact reorder that correctly separates cleanup from error detection, and the new test validates the exact regression, though the global stdout patching in the test is a minor fragility.

  • Verify the production cerebras_agent.go change correctly saves ctxErr := ctx.Err() before the cancel() call to ensure the fix is sound.
  • The captureStdout helper patches os.Stdout globally, which will cause data races or flaky failures if other tests run concurrently in the same package; consider using t.Parallel() carefully or replacing the global patch with dependency injection.
  • Confirm that w.Close() in captureStdout is guaranteed to execute even if fn() panics, ensuring the pipe is drained and os.Stdout is restored via t.Cleanup.

Suggested labels: bug


Posted · 1a0de7c · 1 finding — View review
Proof: 1 model-only
runner-verified = CI receipt · reproduced = sandbox observed diff · grounded = deterministic detector/worker-token · model-only = model judgment only
Dismiss @sigilix dismiss <reason> (not-a-bug | bad-anchor | already-covered | too-minor | wrong-context) · Re-run /sigilix review

@sigilix sigilix Bot added the bug Something isn't working label Jul 11, 2026
@qualitymaxapp

qualitymaxapp Bot commented Jul 11, 2026

Copy link
Copy Markdown

✅ QualityMax Pipeline

Gate Result
🔍 AI Review ✅ Clean
🧪 Repo Tests ✅ 412/412 passed (go)
🤖 AI Tests ✅ 47/51 passed

Powered by QualityMax — AI-Powered Test Automation

Comment on lines +31 to +32
out, _ := io.ReadAll(r)
return string(out)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3 LOGICGROUNDED captureStdout ignores io.ReadAll error, masking pipe-read failures

The captureStdout helper discards the error from io.ReadAll(r) on line 31. If the in-memory pipe read ever fails, the helper returns an empty string and the caller's assertions fail with a misleading "expected the detailed Cerebras error to be printed" message instead of surfacing the actual test-setup failure.

Example:

input: os.Pipe succeeds but io.ReadAll returns an error
actual: captureStdout returns "", test fails with "expected the detailed Cerebras error to be printed, got: \"\""
expected: test fails with "reading captured stdout: <underlying error>"

Current:

	out, _ := io.ReadAll(r)
	return string(out)

Proposed:

out, err := io.ReadAll(r)
	if err != nil {
		t.Fatalf("reading captured stdout: %v", err)
	}
	return string(out)
Suggested change
out, _ := io.ReadAll(r)
return string(out)
out, err := io.ReadAll(r)
if err != nil {
t.Fatalf("reading captured stdout: %v", err)
}
return string(out)
More Info
  • Threat model: A rare pipe-read failure in the test helper produces a confusing assertion failure, making test debugging harder without changing production behavior.
  • Specific code citations: internal/agent/cerebras_agent_test.go line 31: out, _ := io.ReadAll(r) discards the returned error.
  • Existing protections: None; the error is explicitly ignored with _.
  • Proposed mitigation: Capture the error and fail the test explicitly if the pipe read fails: out, err := io.ReadAll(r); if err != nil { t.Fatalf("reading captured stdout: %v", err) }.
  • Alternative mitigations considered: Use t.Cleanup to close the writer, but that still requires checking the read error.
  • Severity calibration: Score 2 because the failure mode is bounded to test diagnostics and in-memory pipe reads essentially never fail in practice.
Prompt To Fix With AI
This is a comment left during a code review.
Path: internal/agent/cerebras_agent_test.go
Line: 31-32

Comment:
**captureStdout ignores io.ReadAll error, masking pipe-read failures**

The `captureStdout` helper discards the error from `io.ReadAll(r)` on line 31. If the in-memory pipe read ever fails, the helper returns an empty string and the caller's assertions fail with a misleading "expected the detailed Cerebras error to be printed" message instead of surfacing the actual test-setup failure.

Example:
input: os.Pipe succeeds but io.ReadAll returns an error
actual: captureStdout returns "", test fails with "expected the detailed Cerebras error to be printed, got: \"\""
expected: test fails with "reading captured stdout: <underlying error>"

Threat model:
A rare pipe-read failure in the test helper produces a confusing assertion failure, making test debugging harder without changing production behavior.

Specific code citations:
`internal/agent/cerebras_agent_test.go` line 31: `out, _ := io.ReadAll(r)` discards the returned error.

Existing protections:
None; the error is explicitly ignored with `_`.

Proposed mitigation:
Capture the error and fail the test explicitly if the pipe read fails: `out, err := io.ReadAll(r); if err != nil { t.Fatalf("reading captured stdout: %v", err) }`.

Alternative mitigations considered:
Use `t.Cleanup` to close the writer, but that still requires checking the read error.

Severity calibration:
Score 2 because the failure mode is bounded to test diagnostics and in-memory pipe reads essentially never fail in practice.

How can I resolve this? If you propose a fix, please make it concise.

golangci-lint's errcheck flagged the unchecked httptest w.Write in the
new regression test, which failed the CI build-and-test job.
@Desperado Desperado merged commit 3109717 into main Jul 11, 2026
7 checks passed
@Desperado Desperado deleted the Desperado/fix-cerebras-backend-error branch July 11, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant