Skip to content

fix(web): return 400 (not 500) for missing required tenant header (#1245)#1247

Merged
iammukeshm merged 1 commit into
developfrom
fix/1245-missing-tenant-400
May 26, 2026
Merged

fix(web): return 400 (not 500) for missing required tenant header (#1245)#1247
iammukeshm merged 1 commit into
developfrom
fix/1245-missing-tenant-400

Conversation

@iammukeshm
Copy link
Copy Markdown
Member

Summary

Fixes #1245 — a tenant-scoped endpoint returned 500 Internal Server Error when the tenant ID was missing, instead of a proper client error.

Root cause

The anonymous, tenant-scoped identity endpoints (forgot-password, reset-password, self-register) bind a required [FromHeader] tenant parameter. When it is missing, ASP.NET Core throws Microsoft.AspNetCore.Http.BadHttpRequestException (which carries StatusCode = 400) during parameter binding. GlobalExceptionHandler did not recognise that type, so it fell through to the generic 500 branch.

Notes from the investigation:

  • Authenticated CRUD endpoints do not reproduce this — the JWT tenant claim resolves the tenant even without the header, so the bug only bites the anonymous endpoints that require the header.
  • It is not a null-reference in Finbuckle's tenant query filter (the filter is null-safe).

Fix

  • GlobalExceptionHandler now maps BadHttpRequestException to its own StatusCode (400, or 413 for oversized bodies, etc.) with a ProblemDetails body. This covers every endpoint with a required bound header/route/query param, not just identity.
  • Mirrored the mapping in the test-only DetailedTestExceptionHandler so tests reflect production behaviour.

Tests

  • 3 integration regression tests: forgot-password / reset-password / self-register without the tenant header now return 400 (were 500).
  • 4 GlobalExceptionHandler unit tests (400, 413, CustomException pass-through, 500 default).
  • Full integration suite: 668 passed, 2 skipped, 0 failed. Backend builds clean (0 warnings).

Docs

Changelog entry: fullstackhero/docs#218

🤖 Generated with Claude Code

fix(web): return 400 (not 500) for malformed requests / missing required params

Anonymous, tenant-scoped endpoints (forgot-password, reset-password,
self-register) bind a required `tenant` header. When it is missing,
ASP.NET Core throws BadHttpRequestException (StatusCode 400) during
parameter binding. GlobalExceptionHandler did not recognise that type
and rendered it as a generic 500.

Map BadHttpRequestException to its own StatusCode so missing required
header/route/query params (and unreadable/oversized bodies) surface as a
proper 400 (or 413, etc.) with a ProblemDetails body. The fix applies to
every endpoint with a required bound parameter, not just identity.

Mirror the mapping in the test-only DetailedTestExceptionHandler, add
integration regression tests for the three identity endpoints, and add
GlobalExceptionHandler unit tests.

Closes #1245

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@
@iammukeshm iammukeshm merged commit c498c52 into develop May 26, 2026
4 checks passed
@iammukeshm iammukeshm deleted the fix/1245-missing-tenant-400 branch May 27, 2026 06:53
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.

[Bug] Missing tenant ID causes 500 error on tenant-scoped endpoint

1 participant