Skip to content

feat(client): surface structured shape errors on TangoValidationError#46

Merged
vdavez merged 1 commit into
mainfrom
fix/validation-error-surface
Jun 10, 2026
Merged

feat(client): surface structured shape errors on TangoValidationError#46
vdavez merged 1 commit into
mainfrom
fix/validation-error-surface

Conversation

@makegov-mark

@makegov-mark makegov-mark Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

What

Addresses the client half of #45: when the API returns a structured 400 (shape errors return {"error": ..., "issues": [{"path", "reason"}], "available_fields": {...}}), the exception message previously surfaced only the top-level error string, and the structured details were reachable only by digging through response_data.

  • Changed: the 400 message now appends each issue's path and reason — Invalid request parameters: Invalid shape: tradeoff_process (unknown_field) instead of Invalid request parameters: Invalid shape.
  • Added: TangoValidationError.issues (list of issue dicts, [] when absent) and TangoValidationError.available_fields (dict or None), mirroring how TangoRateLimitError exposes .wait_in_seconds/.detail over response_data.

Why

Shape errors are currently not self-diagnosable from the exception — callers bisect their shape string by hand (reported in #45). The server already sends everything needed; the client just didn't show it.

Testing

  • Two new unit tests: structured-body case (message, .issues, .available_fields, response_data intact) and plain-body case (accessors return empty defaults).
  • uv run pytest -m "not integration": 332 passed; the one failure (tests/production/test_production_smoke.py::test_search_filters) pre-exists on main and is unrelated (live-API smoke test).
  • ruff check and strict mypy clean on changed files (remaining ruff findings in tests/integration//test_shapes.py pre-exist on main).

Risks

None expected — purely additive; message text changes but message strings aren't part of the surface contract. response_data behavior unchanged.

Notes

Server half of #45 (bare object fields 400ing as unknown_field) is tracked upstream in makegov/tango#2586.

Closes #45

🤖 Generated with Claude Code

400 messages now name the rejected field(s) and reason when the API
returns structured issues, and TangoValidationError gains .issues and
.available_fields accessors over response_data.

Closes #45 (client half; server half tracked in makegov/tango#2586).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vdavez vdavez merged commit bf7c2e0 into main Jun 10, 2026
12 checks passed
@vdavez vdavez deleted the fix/validation-error-surface branch June 10, 2026 18:57
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.

Object fields in available_fields return unknown_field when referenced without sub-selection; client hides structured shape error

1 participant