Skip to content

🤖 Aggregated writes: map other uncertain Coder answers (502/503, broken body read) to the uncertain 504 #242

Open

Description

@ThomasK33

Problem

#241 maps a 2xx *codersdk.Error on the Coder POST that creates a coderworkspace or a codertemplate to an uncertain 504 ("re-read before you retry"). Other create answers that leave the result open still return 500 InternalError, and the message contains the Coder URL (err.Error() of the SDK error):

  1. A proxy in front of Coder answers 502 or 503 after Coder created the object. MapCoderError maps 502/503 to 500.
  2. The connection breaks while the SDK reads a 2xx body, for example a truncated 201. decodeBodyAsJSON returns a plain read response body: ... error without the status (vendor/github.com/coder/coder/v2/codersdk/client.go:558-559). Only a read timeout already maps to 504.
  3. Updates and deletes get the same answers and the same 500.

Workspace start and stop already treat these cases as uncertain (isUncertainStatus in internal/aggregated/storage/workspace_transition.go). Found by the Codex review of #241 (thread on internal/aggregated/coder/errors.go).

Proposal

Decide which write outcomes are uncertain, and map them to the uncertain 504 without the Coder URL. Pre-send failures (DNS, connection refused) cannot be told apart from a broken connection after the send by error type alone. Check *url.Error and the SDK wrapping before you choose. #186 covers the URL in other 5xx errors.

Revisit when

A user reports a duplicate or an unexpected 500 after a create behind a proxy, or #186 changes how 5xx messages are built.


Generated with mux • Model: anthropic:claude-opus-5-5 • Thinking: high

Activity

  1. self-assigned this
    on Oct 13, 2026
  2. ThomasK33 commented on Oct 13, 2026

    @ThomasK33
    MemberAuthor

    One more case for this issue, from the Codex review of #241 (internal/aggregated/coder/errors.go thread):

    1. A create answered with 200 (not the expected 201), Content-Type: application/json and malformed JSON. The SDK goes through ReadBodyAsError, which returns a plain decode body: ... error without the status (vendor/github.com/coder/coder/v2/codersdk/client.go:445-453). It maps to 500. This was the same on codersdk v2.35.8.

    #241 documents this case and the broken body read as cases that still return 500.


    Generated with mux • Model: anthropic:claude-opus-5-5 • Thinking: high

  3. ThomasK33 commented on Oct 13, 2026

    @ThomasK33
    MemberAuthor

    Another case, from the third Codex review of #241 (thread on docs/reference/aggregated-api-behavior.md):

    1. A create answered with 201 application/json and a body of {} or null. ReadBodyAsJSON succeeds, so no error reaches MapCoderCreateError. The converter then calls coder.BuildTemplateName / BuildWorkspaceName with empty segments, and assertNameSegment panics. The generic apiserver's WithPanicRecovery turns it into a 500. The process keeps running. This is older than 🤖 fix: report an unreadable 2xx create answer as an uncertain 504 #241, and it applies to every converted Coder answer (GET, LIST, create), not only creates.

    When this issue is designed, decide whether a create answer without the required fields is an uncertain 504, and whether converters must reject such answers with an error instead of the assertion. The docs sentence in #241 that lists the 2xx answers that still return 500 must then list this case or say "for example".


    Generated with mux • Model: anthropic:claude-opus-5-5 • Thinking: high

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions