fix: add codersdk JSON response decoder for typed API endpoints - #27804
Conversation
Typed SDK methods previously decoded response bodies directly with json.NewDecoder(res.Body).Decode(...). When a reverse proxy, SSO portal, or misconfigured Coder URL returns 200 OK with an HTML body, this surfaced as "invalid character '<' looking for beginning of value" with no context. Add ReadBodyAsJSON next to ReadBodyAsError. It sniffs a bounded body prefix to identify HTML via the media type or a leading '<', streams valid JSON without buffering the whole body, and returns a structured *Error carrying the status code, method, URL, content type, decode cause, and a sanitized bounded body excerpt. Migrate Client.User (coder whoami) and Client.Workspaces (coder list) as the first adopters; remaining typed endpoints migrate in follow-up PRs. Refs #27044
Code reviewNo bugs or CLAUDE.md violations found. One non-blocking suggestion:
Lines 528 to 536 in 033cce1 Lines 551 to 558 in 033cce1 Extracting just the duplicated case and turning the tail into a func htmlBodyError(res *http.Response) *Error {
return invalidBodyError(res, Response{
Message: "Received an HTML response instead of JSON from the Coder API.",
Detail: invalidBodyDetail(res),
}, htmlResponseHelper, nil)
}switch {
case err == nil:
return nil
case body.err != nil && errors.Is(err, body.err):
return xerrors.Errorf("read response body: %w", err)
case len(prefix.bytes) == 0 && errors.Is(err, io.EOF):
return invalidBodyError(res, Response{
Message: "Received an empty response from the Coder API.",
Detail: invalidBodyDetail(res),
}, "", nil)
case isHTMLBody(mimeType, prefix.bytes):
return htmlBodyError(res)
default:
return invalidBodyError(res, Response{
Message: "Received an invalid JSON response from the Coder API.",
Detail: fmt.Sprintf("decode body: %s, %s", err.Error(), invalidBodyDetail(res)),
}, "", err)
} |
Done in 6d2f137 — extracted an htmlBodyError helper for the two identical HTML cases and converted the tail into a switch, exactly as suggested. CI is green :) |
BobbyHo
left a comment
There was a problem hiding this comment.
lgtm with the latest changes. Thank you for addressing my comments.

coder whoamiandcoder listcan surface low-level JSON decode errors when a reverse proxy, SSO portal, or incorrect Coder URL returns HTML with a successful HTTP status.Add a shared SDK JSON response decoder and use it for the user and workspace list endpoints so these commands return a structured, actionable API response error instead. Refs #27044
Reviewed and updated by Coder Agents on behalf of @dylanhuff-at-coder.