Skip to content

fix(runtime): distinguish request parse errors from handler JSON errors#472

Merged
jesseturner21 merged 2 commits into
mainfrom
fix/misleading-json-error-classification
May 12, 2026
Merged

fix(runtime): distinguish request parse errors from handler JSON errors#472
jesseturner21 merged 2 commits into
mainfrom
fix/misleading-json-error-classification

Conversation

@jesseturner21
Copy link
Copy Markdown
Contributor

Summary

  • Fixes misleading "Invalid JSON in request" error when the handler (not the request) raises json.JSONDecodeError (e.g., parsing model output)
  • Narrows the JSONDecodeError/UnicodeDecodeError catches to only cover request.json() parsing
  • Handler-raised exceptions now correctly return HTTP 500 with the actual error message

Resolves V2192037347 — customer reported AgentCore runtime surfaces misleading error classification for downstream application JSON parsing errors.

Test plan

  • Verified bug reproduction: handler JSONDecodeError previously returned 400 "Invalid JSON"
  • Verified fix: handler JSONDecodeError now returns 500 with actual error
  • Verified regression: actual invalid request JSON still returns 400 "Invalid JSON"
  • All 311 runtime unit tests pass

The broad try/except around _handle_invocation caught json.JSONDecodeError
from both request.json() (inbound payload) and the user's handler logic,
reporting both as "Invalid JSON in request" with HTTP 400. This misled
engineers into debugging caller payloads when the root cause was downstream
application/model-output parsing.

Narrow the JSONDecodeError and UnicodeDecodeError catches to only cover
request body parsing. Handler-raised exceptions now fall through to the
generic Exception handler (HTTP 500) with an accurate error message.

Constraint: Runtime contract returns 4xx for request-level errors only
Rejected: Catch handler JSONDecodeError separately with 422 | no precedent in runtime contract
Confidence: high
Scope-risk: narrow
Not-tested: Streaming handlers that raise JSONDecodeError mid-stream
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

✅ No Breaking Changes Detected

No public API breaking changes found in this PR.

Copy link
Copy Markdown
Contributor

@Hweinstock Hweinstock left a comment

Choose a reason for hiding this comment

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

nice fix! Is it possible to verify this with a unit test or even better an integ test?

@jesseturner21
Copy link
Copy Markdown
Contributor Author

Note on CI

The Test (tools) failure is pre-existing and also fails on main (run 25698588721). It's caused by a KMS key policy on account 121875801285 not granting the CI role kms:Decrypt for the BrightData proxy secret. Unrelated to this change.

All relevant checks pass: Test (runtime), Test Python 3.10–3.13, Compat (runtime), Lint and Format.

@Hweinstock
Copy link
Copy Markdown
Contributor

Run uv run pre-commit run --all-files
[INFO] Initializing environment for https://github.com/astral-sh/uv-pre-commit.
[INFO] Initializing environment for https://github.com/astral-sh/ruff-pre-commit.
[INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Initializing environment for https://github.com/PyCQA/bandit.
[INFO] Installing environment for https://github.com/astral-sh/uv-pre-commit.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for https://github.com/astral-sh/ruff-pre-commit.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
uv-lock..................................................................Passed
ruff (legacy alias)......................................................Passed
ruff format..............................................................Failed
- hook id: ruff-format
- files were modified by this hook

1 file reformatted, 219 files left unchanged

trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
check toml...............................................................Passed
check json...............................................................Passed
check yaml...............................................................Passed
check for merge conflicts................................................Passed
check for added large files..............................................Passed
debug statements (python)................................................Passed

lint failing, otherwise LGTM. Thanks for adding the test!

Ensures that a JSONDecodeError raised inside the user's handler returns
HTTP 500 (application error), not HTTP 400 "Invalid JSON" which
misleadingly implies the inbound request payload was malformed.
@jesseturner21 jesseturner21 merged commit 2e8a50a into main May 12, 2026
36 of 37 checks passed
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