Skip to content

fix: response validation returns 500 instead of 422 for nested schemas#1683

Merged
SaltyAom merged 1 commit intoelysiajs:mainfrom
raunak-rpm:fix/1659-validation-nested-schema-error
Jan 23, 2026
Merged

fix: response validation returns 500 instead of 422 for nested schemas#1683
SaltyAom merged 1 commit intoelysiajs:mainfrom
raunak-rpm:fix/1659-validation-nested-schema-error

Conversation

@raunak-rpm
Copy link

@raunak-rpm raunak-rpm commented Jan 17, 2026

Summary

Fixes #1659

When response validation fails on complex nested schemas (Tuples, Unions with Objects), the dynamic handler (aot: false) was returning 500 Internal Server Error instead of 422 Validation Error.

Root Cause

exact-mirror's Clean() function generates code that directly accesses nested properties without null checks. For example, it generates:

ar0p[1].file.ver.s

When called on invalid data (e.g., ver: null instead of ver: {s: '', m: null}), it throws a TypeError: null is not an object.

Solution

Wrap Clean() calls in try-catch in dynamic-handle.ts, consistent with how compose.ts (AOT mode) already handles this:

// compose.ts already does this for AOT mode:
`try{` +
`${name}=validator.${typeAlias}.Clean(${name})\n` +
`}catch{}`

Now dynamic-handle.ts does the same, making both modes consistent.

Changes

  • src/dynamic-handle.ts: Wrap Clean() calls in try-catch blocks
  • test/validator/response-validation-nested.test.ts: Add regression tests

Test Results

Scenario Before After
aot:false invalid nested response ❌ 500 ✅ 422 with error details
aot:true invalid nested response ✅ 422 ✅ 422
aot:false valid response ✅ 200 ✅ 200
aot:true valid response ✅ 200 ✅ 200
Full test suite (437 tests) - ✅ 0 failures

Error Response Example

Now returns proper validation error with path and message:

{
  "type": "validation",
  "on": "response",
  "property": "/items/1/1/file/ver",
  "message": "Expected object",
  "errors": [...]
}

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced error handling for nested response validation, now returning proper 422 validation errors instead of 500 internal server errors when response validation fails.

✏️ Tip: You can customize this high-level summary in your review settings.

elysiajs#1659)

When response validation fails on complex nested schemas (Tuples, Unions with
Objects), the dynamic handler (aot: false) was returning 500 Internal Server
Error instead of 422 Validation Error.

Root cause: exact-mirror's Clean() function generates code that directly
accesses nested properties without null checks. When called on invalid data
(e.g., ver: null instead of ver: {s: '', m: null}), it throws a TypeError.

Fix: Wrap Clean() calls in try-catch in dynamic-handle.ts, consistent with
how compose.ts (AOT mode) already handles this.

- Invalid nested response now returns 422 with proper error details
- Error includes path (/items/1/1/file/ver) and message (Expected object)
- Valid responses still return 200 as expected
- Both aot:true and aot:false now behave consistently

Closes elysiajs#1659
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 17, 2026

Walkthrough

This pull request adds defensive error handling around response validation Clean operations in the dynamic handler, wrapping them in try/catch blocks to gracefully handle Clean failures without cascading crashes. Additionally, a new test suite validates nested response schemas to ensure proper 422 validation errors for nested data mismatches.

Changes

Cohort / File(s) Summary
Response Validation Error Handling
src/dynamic-handle.ts
Introduces try/catch wrapping around response validator Clean calls in multiple code paths. Non-ValidationError exceptions from Clean are caught and converted to ValidationErrors; ValidationErrors are rethrown. Prevents cascading crashes on optional Clean transformation failures.
Nested Response Validation Tests
test/validator/response-validation-nested.test.ts
New test suite with three tests covering nested response schema validation for both aot: false and aot: true modes. Validates that malformed nested responses return 422 status with proper validation error payloads instead of 500 errors.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • PR #1634: Modifies when Clean is created/applied for schemas with patternProperties in response validation, directly related to how Clean operations are handled in response validation logic.

Poem

🐰 Nested data danced with errors so deep,
Clean wrapped in shields now puts bugs to sleep.
Try-catch guards the validation way,
No more crashes to ruin the day!
Response schemas nestled safe and sound,
In 422 errors, sweet truth is found. 🛡️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: wrapping Clean() calls in try-catch to fix response validation that was returning 500 instead of 422 for nested schemas.
Linked Issues check ✅ Passed The PR directly addresses issue #1659 by wrapping Clean() calls in try-catch within src/dynamic-handle.ts to handle nested validation errors gracefully and return 422 instead of 500, plus adds comprehensive regression tests.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the nested response validation issue: error handling in dynamic-handle.ts and regression tests in response-validation-nested.test.ts, with no unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 17, 2026

Open in StackBlitz

npm i https://pkg.pr.new/elysiajs/elysia@1683

commit: 2872e3b

@SaltyAom SaltyAom merged commit f8a52b9 into elysiajs:main Jan 23, 2026
3 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.

Validation loose errors

3 participants