Skip to content

whoami returns 500 for users with reserved-TLD email addresses (.test/.local): create/read validation asymmetry #460

Description

@granludo

Summary

GET /creator/user/whoami returns HTTP 500 for any user whose email address uses a reserved or special-use TLD (.test, .local, .invalid, …). The user can be created and can log in normally — only whoami fails, and it fails permanently for that account.

Reproduction

lamb login -s http://localhost:9099 -e admin@owi.com -p <admin-pass>
lamb user create someone@example.test "Some One" <password> -t creator   # succeeds
lamb login -s http://localhost:9099 -e someone@example.test -p <password> # succeeds
lamb whoami                                                               # Error: API error (500)

The same user with a @example.com address works correctly. Reproduced on dev (2026-08-01) via lamb-cli; the endpoint is shared with the frontend, so any client is affected.

Root cause

The response model validates email as EmailStr, and email-validator rejects reserved TLDs. FastAPI raises ResponseValidationError after the handler has done its work, which surfaces as an unhandled 500:

fastapi.exceptions.ResponseValidationError: 1 validation errors:
  {'type': 'value_error', 'loc': ('response', 'email'),
   'msg': 'value is not a valid email address: The part after the @-sign is a
           special-use or reserved name that cannot be used with email.',
   'input': 'vk-check@lamb.test'}

The underlying defect is an asymmetry between the write path and the read path: user creation accepts an address that the read path cannot serialize. Any account created that way is left in a state where it exists, authenticates, and works for other endpoints, but cannot report its own identity.

Impact

  • Test, staging, and CI environments routinely use .test / .local addresses; every such account is broken on whoami, and the failure mode (500, no message) gives no clue why.
  • The mismatch is silent at creation time — nothing warns that the address will break later.

Suggested fix

Make the two paths agree, in whichever direction the project prefers:

  1. Relax the response model (plain str, or EmailStr with special-use domains permitted) so anything creatable is serializable; or
  2. Apply the same validation at user creation and reject the address up front with a clear message.

Option 1 is the smaller change and keeps test environments usable. Either way, a regression test should create a user with a reserved-TLD address and assert that whoami responds cleanly.

Provenance

Found by an automated black-box agent test run (organization-bootstrap module) and verified by hand. The agent originally attributed the failure to non-admin role, which was incorrect — a .com non-admin creator user returns 200 — the determining variable is the email domain.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions