Skip to content

fix: Replace NULL sentinels in form data and tolerate malformed validation errors - #646

Open
razor-x wants to merge 2 commits into
mainfrom
claude/python-sdk-audit-o2iid9-13-null-data-validation
Open

fix: Replace NULL sentinels in form data and tolerate malformed validation errors#646
razor-x wants to merge 2 commits into
mainfrom
claude/python-sdk-audit-o2iid9-13-null-data-validation

Conversation

@razor-x

@razor-x razor-x commented Aug 27, 2026

Copy link
Copy Markdown
Member

What

Two small hardening fixes from the SDK audit's L5 grab-bag:

NULL in form data (L5c). The client's request override applied replace_null to json= bodies and search params but not to data= — so the documented NULL sentinel form-encoded via str() as the literal string "NULL". No generated route uses data=, but it is part of the documented seam.client.post(...) escape hatch. Mapping-shaped data= now gets the same replace_null pass in both clients (name=NULL&kept=valuename=&kept=value).

Malformed validation_errors shapes (L5d). SeamHttpInvalidInputError trusted the server's validation_errors envelope: a list/string envelope, or a parameter entry that isn't a dict, raised AttributeError from inside the accessors — and the validation_errors property added in #631 walks every key, so a single oddly-shaped entry blew up the whole accessor. Both accessors now degrade to "no validation details" ([]) for anything but the expected object-of-objects shape, while well-formed entries next to malformed ones still surface.

Also teaches the test suite's recording server to record form-encoded bodies as text instead of failing to JSON-parse them.

Testing

New test/null_data_test.py: wire assertion that the sentinel form-encodes as an empty value; list/string envelopes and non-dict/non-list parameter values return [] without raising, with well-formed siblings intact.

Revert check: with seam/client.py and seam/exceptions.py reverted, the tests fail with the audit's symptoms — name=NULL&kept=value on the wire and AttributeError: 'list' object has no attribute 'get'.

Full suite: 190 passed; mypy, pylint (10.00), black clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Y1RzepycXEYA3LStfjt8cY


Generated by Claude Code

…ation errors

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y1RzepycXEYA3LStfjt8cY
@razor-x
razor-x requested a review from a team as a code owner August 27, 2026 22:02
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.

2 participants