Repository navigation
Show API error messages as text instead of raw JSON - #260
Open
sanieldalib wants to merge 1 commit into
Open
sanieldalib wants to merge 1 commit into
sanieldalib wants to merge 1 commit into
Conversation
sanieldalib
force-pushed
the
salib/readable-api-errors
branch
2 times, most recently
from
November 13, 2026 21:48
908fde7 to
c81924d
Compare
sanieldalib
changed the base branch from
main
to
salib/grid-overwrite-warning
November 13, 2026 21:48
A failed API call printed the response body verbatim, so a multiline message showed up as one long line of JSON with escaped newlines. The status, code and message now print as text: one line for a one-line message, and the message indented on its own lines otherwise. --verbose adds the raw body, and JSON output still carries it in the message. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sanieldalib
force-pushed
the
salib/readable-api-errors
branch
from
November 13, 2026 22:20
c81924d to
05849ad
Compare
sanieldalib
marked this pull request as ready for review
November 13, 2026 22:27
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Decoded JSON messages and error codes can emit unsanitized terminal controls to stderr, allowing screen clearing or overwritten diagnostics; sanitization and an escaped-ANSI regression test are needed.
1 open issue
What changed in this PR
This PR makes API failures easier to read in the CLI by displaying decoded messages instead of raw JSON, while preserving JSON output and exit codes.
Changes:
- Formats single-line and multiline API messages with HTTP status, error code, and command context.
- Includes the raw response body in verbose output and preserves fallback behavior for unreadable bodies.
- Adds formatting tests and clarifies the JSON error message documentation.
| File | Description |
|---|---|
internal/cmd/errors.go |
Extracts API responses and formats readable error messages. |
internal/cmd/errors_test.go |
Tests message formatting, verbose output, JSON preservation, and fallback behavior. |
internal/cmd/command.go |
Applies readable formatting when printing command failures to stderr. |
cmd/errors.go |
Clarifies that JSON error messages retain the raw response body. |
Review effort: Balanced
Comment on lines
+178
to
+184
| message = strings.TrimSpace(message) | ||
| if message == "" { | ||
| return "", false | ||
| } | ||
| statusText := fmt.Sprintf("HTTP %d", status) | ||
| if code := cmp.Or(body.Code, body.ErrorCode); code != "" { | ||
| statusText += ", " + code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

🚀 What
The API no longer appends pydantic's
For further information visit https://errors.pydantic.dev/…line to validation messages (a server-side change), so the "after" examples below show the message as the API now returns it. The "before" example is the body as it was captured.Before and after
Captured from
mainand this branch, built locally, runningbaseten grid route listagainst a local server that replays each response body. The 400 body is a real validation error from the API.Multiline message (HTTP 400)
Before:
After:
One-line message (HTTP 403)
Proxy body with only
error(HTTP 401)--verbose(after only)Live API, 404 (after only)
--verboseadds the raw response body below the message.--output jsonstill carries the raw body inmessage, plusapi_status_code,api_error_codeandapi_details. Exit codes are unchanged. A body with no readable message (HTML from a proxy, for example) still prints as before.💻 How
apiErrorTextininternal/cmd/errors.gofinds the API response in the error chain, reads the message frommessage, or fromerrorordetailwhen those are strings (inference API and proxies), and keeps whatever the command wrapped around it (listing Grid API keys:).messagekeeps the raw body; theJSONError.Messagedoc comment no longer claims it is identical to stderr.sandbox.APIError, which is already decoded and prints its own format.🔬 Testing
errors_test.goreplay that 400 body throughorg billing usageand assert the exact stderr text, plus the one-line, proxy (erroronly),--verbose, JSON and non-JSON-body cases.TestJSONError*tests pass unchanged.go test ./...passes exceptTest_Grid_Setup_RealHarnessandTest_Grid_ClaudeServedModel_RealClaudeCode, which fail the same way on unmodifiedmainon my machine (they drive locally installed harnesses).🤖 Generated with Claude Code