hcengineering/platform · error · HttpError
Unauthorized
Error message
Unauthorized
What it means
withAuthorization middleware extracts a bearer/auth token from request headers. If extractToken returns null (no Authorization header, malformed scheme, etc.), it throws HttpError 401 which express passes to the error handler as 'Unauthorized'.
Source
Thrown at pods/link-preview/src/middleware.ts:45
export interface RequestWithAuth extends Request {
token?: Token
}
export const keepAlive = (options: KeepAliveOptions): RequestHandler => {
const { timeout, max } = options
return (req: Request, res: Response, next: NextFunction) => {
res.setHeader('Connection', 'keep-alive')
res.setHeader('Keep-Alive', `timeout=${timeout}, max=${max}`)
next()
}
}
export const withAuthorization = (req: RequestWithAuth, res: Response, next: NextFunction): void => {
try {
const token = extractToken(req.headers)
if (token == null) {
throw new HttpError(401, 'Unauthorized')
}
req.token = token
next()
} catch (err: any) {
next(err)
}
}
export interface ErrorHandlerOptions {
ctx: MeasureContext
}
export const errorHandler = (options: ErrorHandlerOptions): ErrorRequestHandler => {
const { ctx } = options
return (err: any, req: Request, res: Response, _next: NextFunction): void => {
ctx.error(err.message, { code: err.code, message: err.message })View on GitHub (pinned to 63e28dc964)
Solutions
- Send a valid Authorization header, e.g. 'Authorization: Bearer <token>'
- Check extractToken's expected header format and match it in the client
- Verify no proxy/gateway strips the Authorization header
Example fix
// before
fetch('/api/link-preview?url=...')
// after
fetch('/api/link-preview?url=...', { headers: { Authorization: 'Bearer ' + token } }) Defensive patterns
Strategy: validation
Validate before calling
const token = localStorage.getItem('token')
if (!token) throw new Error('Not authenticated: attach Authorization header before calling API')
// then: headers: { Authorization: `Bearer ${token}` } Try / catch
try {
const res = await fetch(url, { headers: { Authorization: 'Bearer ' + token } })
return await res.json()
} catch (err) {
if (res?.status === 401) { redirectToLogin(); return }
throw err
} Prevention
- Attach the Authorization header in a shared fetch/axios interceptor
- Check header format matches extractToken's expectations (scheme + token)
- Ensure proxies don't strip Authorization headers
- Refresh tokens before expiry
When it happens
Trigger: Calling any link-preview endpoint without an Authorization header; header present but not in the format extractToken expects (e.g. missing 'Bearer ' prefix); empty token string.
Common situations: Client forgot to attach token after login; reverse proxy stripping Authorization header; frontend using different auth scheme than the middleware expects; curl tests omitting -H flag.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- platform.status.Unauthorized
- Couldn't find workspace with the provided token
- Unauthorized
- Token error
- Missing account in token
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/4a0ec19f32b00211.
Report an issue: GitHub.