Repository navigation
Conversation
RPCClient.call did ServerError(**err["error"]). That raised TypeError
instead of ServerError, hiding the server's message, whenever the error
body was not an object with exactly ServerError's keywords:
- a string error: "argument after ** must be a mapping, not str" (seen in
production from the RAST genome_annotation service at
tutorial.theseed.org, the endpoint RastClient uses);
- a JSON-RPC 2.0 error object, which has no "name": "missing 1 required
positional argument: 'name'";
- an error object with another key: "unexpected keyword argument";
- a JSON body that is not an object: "string indices must be integers".
Build ServerError from a dict error with .get() defaults ("Unknown", 0),
and use the existing "Unknown" ServerError with the response text for
anything else, as for a 500 without an "error" key.
Tests: a full error object, and the four shapes above.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this matters in our workflow
We annotate genomes with RAST, and RAST is reached through
RPCClient:RastClientuses it, and so does theModelSEED API. When the server returns an HTTP 500, callers should get a
ServerErrorwith the server's message.Instead, for several common body shapes they get a
TypeErrorraised from insiderpcclient.py. The string case hashappened in production: on 30 Jun 2026 the ModelSEED API's failure watcher logged it twice, from its RAST annotation
step (ModelSEED/modelseed-api-ops #18 and #19).
What happens
rpcclient.pyL71-L79 at 062714bdoes
raise ServerError(**err["error"]). That works only when the error is an object whose keys are exactlyServerError's parameters. Other shapes raiseTypeErroron that line:{"error": "service unavailable"}TypeError: ... argument after ** must be a mapping, not str{"error": {"code": -32601, "message": "Method not found"}}(JSON-RPC 2.0, noname)TypeError: ServerError.__init__() missing 1 required positional argument: 'name'{"error": {"name": "Err", "code": 1, "message": "m", "stack": "..."}}TypeError: ServerError.__init__() got an unexpected keyword argument 'stack'"internal error"(a JSON string, not an object)TypeError: string indices must be integersHow to reproduce
The fix
ServerErrorfrom its keys, with defaults for missing ones and extra keys ignored."Unknown"branch with the response text, as a 500 without anerrorkey alreadydoes.
ServerErroras before.RPCClienthas one caller inside the package,RastClient(rast_client.py:57). For it, only the exception type ofa failing call changes, from
TypeErrortoServerError.Tests
This adds a new file,
tests/core/test_rpcclient.py(there were noRPCClienttests). It monkeypatchesrequests.postand checks:test_call_server_error: a complete error object keeps itsname,codeandmessage. This locks in the currentbehaviour, and it passes on dev.
test_call_server_error_other_shapes, parametrized over the four bodies in the table: each raises aServerErrorwith the expected
name,codeand message.Against dev's code, the four other-shapes cases fail and
test_call_server_errorpasses:With the fix, all 5 pass. Full suite (Python 3.10, cobra 0.32.1):
tests/coregoes from 56 to 61 passed, andtests/from 58 to 63.black22.8.0 and the other pre-commit hooks pass.Related
TypeErrorfor the other shapes.🤖 Generated with Claude Code