Skip to content

OUT-4013: stop raw ZodError on GET / from unauthenticated renders - #232

Merged
SandipBajracharya merged 5 commits into
mainfrom
OUT-4013
Aug 6, 2026
Merged

OUT-4013: stop raw ZodError on GET / from unauthenticated renders#232
SandipBajracharya merged 5 commits into
mainfrom
OUT-4013

Conversation

@SandipBajracharya

Copy link
Copy Markdown
Collaborator

Changes

  • authenticateHeaders no longer calls z.string().parse(undefined). When the proxy did not inject auth headers (invalid/expired token → withErrorHandler returns NextResponse.next() for non-API routes, so render proceeds unauthenticated), it now throws the existing domain errors AssemblyMissingHeadersError / AssemblyInvalidTokenError instead of a raw ZodError.
  • The missing-header name is logged server-side via console.warn; the thrown error message stays generic so withErrorHandler can't leak the detail to API clients.
  • onRequestError (instrumentation) now filters expected 401-class auth failures (AssemblyMissingHeadersError, AssemblyInvalidTokenError, AssemblyTokenParseError) instead of reporting them to Sentry as unhandled errors.
  • global-error.tsx reverted to a plain Sentry.captureException + comment — server errors are redacted in prod, so type-based filtering there is a no-op.
  • Unit tests added for both authenticateHeaders and onRequestError.

Fixes CLIENT-HOME-V3-1K (Sentry).

Testing Criteria

  • pnpm typecheck, pnpm lint, pnpm test (48 passing), and pnpm build (no Edge Runtime warnings) all pass.
  • authenticateHeaders unit tests: valid internal-user and client headers return the correct User; missing token/workspaceId throws AssemblyMissingHeadersError and the diagnostic names the missing header; missing both internalUserId and clientId throws AssemblyInvalidTokenError.
  • onRequestError unit tests: expected auth errors are skipped (not sent to Sentry); a generic Error and a non-Error thrown value are still forwarded to Sentry.
  • Loom: to add

Notes

  • No dependencies on other PRs.
  • The docs: commit (engineering notes in AGENTS.md) is unrelated to the fix and included only for convenience; can be dropped if preferred.

Impact & Surface Area of Change

  • Touches the auth layer (authenticateHeaders) called by the root layout and ~10 API route controllers, plus the global instrumentation error hook. Happy-path behavior is unchanged (same User shape returned).
  • The only behavior change for unauthenticated requests: a clean domain error + server log instead of an unhandled ZodError, and these expected 401-class failures no longer create Sentry noise. Worth a regression glance at authenticated page loads and API routes to confirm normal auth still works.

SandipBajracharya and others added 4 commits August 6, 2026 14:09
…f raw ZodError

When the proxy does not inject auth headers (invalid/expired token), the home
route render reached authenticateHeaders, where z.string().parse(undefined)
threw a raw ZodError. Replace the bare parses with explicit presence checks
that throw the existing AssemblyMissingHeadersError / AssemblyInvalidTokenError,
and log which header is missing server-side (message kept generic to avoid
leaking detail to API clients).

Fixes CLIENT-HOME-V3-1K

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wrap onRequestError so 401-class auth errors (missing headers, invalid token,
token parse) are skipped instead of reported as unhandled errors. Revert the
global-error name-based filter to a plain capture: server errors are redacted
in prod, so type-based filtering there is a no-op.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Unit tests for authenticateHeaders (all header combinations, and the missing-
header diagnostic naming the right header) and for onRequestError (skips
expected auth errors, forwards generic and non-Error values to Sentry).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Conventions for const-over-let, short comments, and DRY/KISS/SOLID/YAGNI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Aug 6, 2026

Copy link
Copy Markdown

OUT-4013

@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
client-home-v3 Ready Ready Preview Aug 6, 2026 8:37am

Request Review

@SandipBajracharya SandipBajracharya changed the title fix(OUT-4013): stop raw ZodError on GET / from unauthenticated renders OUT-4013: stop raw ZodError on GET / from unauthenticated renders Aug 6, 2026
@greptile-apps

greptile-apps Bot commented Aug 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR replaces raw missing-header validation failures with domain-specific authentication errors and narrows Sentry suppression to the expected missing-header case.

  • Validates required proxy-injected headers before constructing the authenticated user.
  • Logs missing-header diagnostics without exposing header names through thrown error messages.
  • Suppresses only AssemblyMissingHeadersError in request instrumentation while forwarding other authentication and unexpected failures.
  • Adds unit coverage for header authentication and request-error reporting behavior.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/features/auth/lib/authenticate.ts Replaces raw Zod failures for absent required headers with generic domain errors and server-side diagnostics while preserving the authenticated User shape.
src/instrumentation.ts Narrows request-error suppression to AssemblyMissingHeadersError, resolving the previously reported loss of SDK-failure reporting.
src/app/global-error.tsx Retains standard client-side Sentry capture and documents why server authentication filtering occurs in instrumentation.
tests/unit/authenticate-headers.test.ts Covers missing required headers, invalid identity headers, diagnostics, and valid internal and client users.
tests/unit/on-request-error.test.ts Confirms expected missing-header errors are suppressed while invalid-token, token-parse, generic, and non-Error values are forwarded.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Incoming request] --> B[Proxy authentication]
    B --> C[Root or API authentication]
    C --> D{Required headers present?}
    D -- No --> E[AssemblyMissingHeadersError]
    E --> F[Server warning]
    E --> G[onRequestError suppresses expected noise]
    D -- Yes --> H{User identity present?}
    H -- No --> I[AssemblyInvalidTokenError]
    I --> J[onRequestError forwards to Sentry]
    H -- Yes --> K[Authenticated User]
Loading

Reviews (2): Last reviewed commit: "fix(OUT-4013): only suppress AssemblyMis..." | Re-trigger Greptile

Comment thread src/instrumentation.ts Outdated
AssemblyClient's constructor converts any SDK init rejection (config, service,
network) into AssemblyInvalidTokenError, which reaches onRequestError via the
unwrapped root render path. The previous class-wide filter dropped those real
failures from Sentry. Narrow the filter to AssemblyMissingHeadersError only —
the genuine OUT-4013 unauthenticated-request noise — so SDK/config failures and
token-parse errors keep their error-level report.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@SandipBajracharya

Copy link
Copy Markdown
Collaborator Author

@greptileai review PR again

@priosshrsth priosshrsth left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

lgtm

@SandipBajracharya
SandipBajracharya merged commit 4993790 into main Aug 6, 2026
8 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