Skip to content

fix(binder): serialize BindingError to structured JSON (#2771)#3004

Merged
vishr merged 2 commits into
masterfrom
fix-2771-binding-error-json
Jun 13, 2026
Merged

fix(binder): serialize BindingError to structured JSON (#2771)#3004
vishr merged 2 commits into
masterfrom
fix-2771-binding-error-json

Conversation

@vishr

@vishr vishr commented Jun 13, 2026

Copy link
Copy Markdown
Member

Problem (#2771)

A binding error returned from a handler is serialized as {"message":"Bad Request"} — the field name and the binder message are both lost.

Root cause

BindingError embeds *HTTPError but does not implement json.Marshaler. In DefaultHTTPErrorHandler the type switch runs on the HTTPStatusCoder extracted via errors.As, whose dynamic type is *BindingError. Go's case *HTTPError matches only the exact type, so a *BindingError falls through to the default branch → {"message": http.StatusText(code)}. Regression from fbfe216 (#2456).

Verified on current master:

GET /doc?docNum=abc  →  400  {"message":"Bad Request"}

Fix

Implement MarshalJSON on *BindingError so it takes the handler's existing case json.Marshaler branch (which is checked before *HTTPError). Restores the v4.10.2 structured response:

GET /doc?docNum=abc  →  400  {"field":"docNum","message":"failed to bind field value to int"}

This is the approach the maintainer outlined in the issue thread ("we could make echo.BindingError … implement json.Marshaler").

Test

TestBindingError_serializesToStructuredJSON (written first; fails on master with field=<nil>, message="Bad Request"). gofmt/vet clean; full root-package suite passes.

Fixes #2771.

🤖 Generated with Claude Code

vishr and others added 2 commits June 13, 2026 13:00
BindingError embeds *HTTPError but did not implement json.Marshaler, so
DefaultHTTPErrorHandler's type switch fell through to its default branch
(the value is a *BindingError, not a *HTTPError), flattening responses to
{"message":"Bad Request"} and dropping both the field name and the binder
message — a regression from fbfe216.

Implement MarshalJSON on *BindingError so it takes the handler's
json.Marshaler branch, restoring the structured {"field":...,"message":...}
response (the v4.10.2 behavior).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…llback (#2771)

- Note on the struct that serialization goes through MarshalJSON (the json
  tags are documentation only now).
- Add a test for the empty-message -> status-text fallback branch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vishr vishr merged commit dba8ff6 into master Jun 13, 2026
8 checks passed
@vishr vishr deleted the fix-2771-binding-error-json branch June 13, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Binding errors no longer return a structured error response

1 participant