Skip to content

Fix PATCH /transactions success response code: 209 -> 200#34

Merged
bradymholt merged 1 commit into
ynab:mainfrom
emigre459:fix/update-transactions-status-code
Jul 15, 2026
Merged

Fix PATCH /transactions success response code: 209 -> 200#34
bradymholt merged 1 commit into
ynab:mainfrom
emigre459:fix/update-transactions-status-code

Conversation

@emigre459

Copy link
Copy Markdown
Contributor

Fixes #33.

What's wrong

updateTransactions (PATCH /transactions) declares its success response as HTTP 209 in open_api_spec.yaml, but the real API returns 200. Since the generated _response_types_map in TransactionsApi.update_transactions() / _with_http_info() / _without_preload_content() only has an entry for '209', every real successful call silently deserializes to data=None instead of raising or returning the parsed SaveTransactionsResponse -- see #33 for the full repro and impact (a caller checking response.data after a non-exception call gets an AttributeError, even though the mutation already applied server-side).

Every other TransactionsApi endpoint has a correctly-mapped status code; this is isolated to the one batch-update endpoint.

What this changes

  • open_api_spec.yaml: "209" -> "200" for updateTransactions's success response (the only "209" in the whole spec).
  • ynab/api/transactions_api.py: the three matching _response_types_map entries (update_transactions, update_transactions_with_http_info, update_transactions_without_preload_content).
  • docs/TransactionsApi.md: the corresponding status-code table row.
  • tests/test_response_deserialize.py: a new regression test that calls the real generated update_transactions_with_http_info() (not a hand-supplied response_types_map, so it actually exercises the embedded map) against a mocked 200 response and asserts result.data is not None. I verified this test fails against the pre-fix code (result.data is None) and passes after the fix.

I don't have openapi-generator available locally, so this is a precise hand-patch of the single changed value rather than a full regenerate -- following the same pattern as #3. docs/, spec, and generated code all agree, and the full existing suite (161 tests) plus the new one (162 total) pass.

One thing worth flagging for maintainers: scripts/generate.sh re-downloads open_api_spec.yaml fresh from https://api.ynab.com/papi/open_api_spec.yaml on every regen, so this fix could get silently reverted by the next Generate from server spec PR unless the same 209->200 correction also lands in YNAB's canonical spec. I don't have visibility into that system, so noted in #33 in case it needs a separate internal escalation.

Testing

$ poetry run pytest
============================= 162 passed in 0.46s ==============================

The updateTransactions (PATCH /transactions) operation's spec declared
its success response as HTTP 209, but the real API returns 200.
Because 200 didn't match the generated _response_types_map, every
real, successful call to update_transactions()/_with_http_info()/
_without_preload_content() silently deserialized to data=None instead
of a SaveTransactionsResponse -- the mutation had already applied
server-side, but callers had no way to observe the result and calling
code that assumed a non-exception response is parseable (e.g.
response.data.transactions) would crash with an AttributeError on a
successful request.

Fixes open_api_spec.yaml, the three generated
TransactionsApi.update_transactions* methods, and the corresponding
docs table entry. Adds a regression test that calls the real
generated update_transactions_with_http_info() (not a hand-supplied
response_types_map) against a mocked 200 response, confirmed to fail
against the pre-fix code and pass after.

Found via a downstream MCP server project that calls this endpoint
for its "update multiple transactions" write tool.

@bradymholt bradymholt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good. Thanks for the fix! I'll get the fix made to our official OpenAPI spec as well so that regenerations of the client will continue work correctly.

@bradymholt
bradymholt merged commit b78f32e into ynab:main Jul 15, 2026
2 checks passed
@github-actions

Copy link
Copy Markdown

The changes in this PR were just released in 4.3.0 🎉.

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.

PATCH /transactions (update_transactions) success response mapped to HTTP 209 instead of 200 -- silently returns data=None on real success

2 participants