calcom/cal.diy · error · BadRequestException
Missing 'Bearer' Authorization header.
Error message
Missing 'Bearer' Authorization header.
What it means
Thrown by POST /exchange when the Authorization header is absent or yields an empty string after .replace('Bearer ', '').trim(). The endpoint expects the one-time authorization code to be delivered as a Bearer token in the Authorization header (not in the body). Missing/malformed header → BadRequestException (HTTP 400).
Source
Thrown at apps/api/v2/src/modules/oauth-clients/controllers/oauth-flow/oauth-flow.controller.ts:93
);
}
const { id } = await this.tokensRepository.createAuthorizationToken(clientId, userId);
return res.redirect(`${body.redirectUri}?code=${id}`);
}
@Post("/exchange")
@HttpCode(HttpStatus.OK)
@DocsExcludeEndpoint()
async exchange(
@Headers("Authorization") authorization: string,
@Param("clientId") clientId: string,
@Body() body: ExchangeAuthorizationCodeInput
): Promise<KeysResponseDto> {
const authorizeEndpointCode = authorization.replace("Bearer ", "").trim();
if (!authorizeEndpointCode) {
throw new BadRequestException("Missing 'Bearer' Authorization header.");
}
const tokens = await this.oAuthFlowService.exchangeAuthorizationToken(
authorizeEndpointCode,
clientId,
body.clientSecret
);
return {
status: SUCCESS_STATUS,
data: tokens,
};
}
@Post("/refresh")
@HttpCode(HttpStatus.OK)
@UseGuards(ApiAuthGuard)
@DocsTags("Deprecated: Platform / Managed Users")View on GitHub (pinned to 176037d0af)
Solutions
- Set the header exactly: Authorization: Bearer <authorizationCode> where authorizationCode is the code returned from /authorize.
- Verify the code is non-empty before constructing the header.
- Ensure no proxy/gateway strips the Authorization header.
- Use the same code value from the redirect ?code= param, not the client secret.
Example fix
// before
await fetch(`/v2/oauth-clients/${clientId}/exchange`, { method: 'POST', body: JSON.stringify({ clientSecret }) });
// after
await fetch(`/v2/oauth-clients/${clientId}/exchange`, {
method: 'POST',
headers: { Authorization: `Bearer ${code}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ clientSecret }),
}); Defensive patterns
Strategy: validation
Validate before calling
// Build and validate the Bearer header before sending
function bearerHeader(code: unknown) {
if (typeof code !== 'string' || code.trim() === '') {
throw new Error('authorization code is required');
}
return { Authorization: `Bearer ${code}` };
}
await fetch(`/v2/oauth-clients/${clientId}/exchange`, {
method: 'POST',
headers: { ...bearerHeader(code), 'Content-Type': 'application/json' },
body: JSON.stringify({ clientSecret }),
}); Type guard
function isNonEmptyBearerCode(value: unknown): value is string {
return typeof value === 'string' && value.trim().length > 0;
} Try / catch
if (!code) throw new Error('Missing authorization code for Bearer header');
// (No try/catch needed if validated up front; the server error is purely a client omission.) Prevention
- Always set Authorization: Bearer <code> on /exchange.
- Take the code verbatim from the redirect ?code= param.
- Ensure proxies do not strip the Authorization header.
When it happens
Trigger: Calling POST /exchange without setting the Authorization header at all; sending 'Bearer' with no trailing token; sending 'Bearer ' (trailing space only); sending the code in the request body instead of the header; sending a header with a different scheme like 'Basic'.
Common situations: Client library that puts credentials in the body by default; a header-stripping proxy or CORS preflight that drops Authorization; a typo in the header name; sending the raw code without the 'Bearer ' prefix.
Related errors
- Invalid Authorization Token.
- Failed to fetch Basecamp projects
- PermissionsGuard - no authentication provided. Provide eithe
- PermissionsGuard - oAuth client with id=${oAuthClient.id} do
- PermissionsGuard - no oAuth client found for access token=${
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/bfa2e5d898b3a3ac.
Report an issue: GitHub.