Skip to content

Aggregated writes: follow-ups after #400 (forged answers, 3xx without Location, log detail, stop build 201 {}) #421

Closed

Description

@ThomasK33

Follow-ups from the review and independent verification of #400 (which fixes #242). Each item was deferred with a reason on its review thread. None of them makes a write that reached Coder return the non-uncertain 500.

  1. Forged success answers. A build answer with an invented nonzero build ID, or a template metadata answer with the right template ID but stale content, passes the checks. A real Coder failure does not produce these answers; only a misbehaving proxy does. Threads: 🤖 fix: map uncertain aggregated write answers to 504 and list unconfigured namespaces as empty #400 (comment), 🤖 fix: map uncertain aggregated write answers to 504 and list unconfigured namespaces as empty #400 (comment)
  2. A proxy 3xx without Location comes back as a 3xx *codersdk.Error, and the write maps to the 500 that MapCoderError gives a 300. Thread: 🤖 fix: map uncertain aggregated write answers to 504 and list unconfigured namespaces as empty #400 (comment)
  3. Lost log detail. When the re-read after a template activation fails, the coder-errors log no longer carries the original status or transport error. Thread: 🤖 fix: map uncertain aggregated write answers to 504 and list unconfigured namespaces as empty #400 (comment)
  4. Workspace create with spec.running=false. If the stop build POST answers 201 {}, the storage replaces the real latest build with an empty one, so the API reports an empty build ID. Thread: 🤖 fix: map uncertain aggregated write answers to 504 and list unconfigured namespaces as empty #400 (comment)
  5. HTTP/1.1 partial headers. A request whose headers are only partly written before the connection fails reaches the server without the WroteHeaders trace hook firing. The write error still maps to the uncertain 504, so the contract holds, but the "headers written" marker is not a complete record of what the server saw.
  6. Go's HTTP/2 client re-sends a POST after RST_STREAM(PROTOCOL_ERROR) (x/net/http2: Server rejects Transport with ErrCodeProtocol stream error golang/go#47635). When that retry succeeds, Coder receives the write twice. This is Go behavior, and in-cluster plain-HTTP Coder uses HTTP/1.1, so it applies only to HTTPS endpoints that negotiate HTTP/2.

Trigger: a user report of a duplicate or a wrong error code behind a proxy, or the next change to internal/aggregated/coder/errors.go.

Refs #242, #400


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

Metadata

Metadata

Assignees

No one assigned

    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