twentyhq/twenty · critical · RestApiClientError
Missing application access token. Set the `${DEFAULT_APP_ACC
Error message
Missing application access token. Set the `${DEFAULT_APP_ACCESS_TOKEN_NAME}` environment variable or pass `token` to `RestApiClient`. What it means
Thrown by RestApiClient.resolveToken (rest/index.ts:208-215) as a RestApiClientError when no authorization source is available: no `token` in constructor options, no TWENTY_ACCESS_TOKEN env var, and no TWENTY_API_KEY env var. The client tries each in order and fails the request if all are missing/empty.
Source
Thrown at packages/twenty-client-sdk/src/rest/index.ts:212
};
}
private resolveToken(): string {
if (!isDefined(this.authorizationToken)) {
const processEnvironment = getProcessEnvironment();
this.authorizationToken =
this.token ??
processEnvironment[DEFAULT_APP_ACCESS_TOKEN_NAME] ??
processEnvironment[DEFAULT_API_KEY_NAME] ??
null;
}
if (
!isDefined(this.authorizationToken) ||
this.authorizationToken.length === 0
) {
throw new RestApiClientError(
`Missing application access token. Set the \`${DEFAULT_APP_ACCESS_TOKEN_NAME}\` environment variable or pass \`token\` to \`RestApiClient\`.`,
);
}
return this.authorizationToken;
}
private async requestRefreshedAccessToken(): Promise<string | null> {
const refreshAccessTokenFunction = (
globalThis as {
frontComponentHostCommunicationApi?: {
requestAccessTokenRefresh?: () => Promise<string>;
};
}
).frontComponentHostCommunicationApi?.requestAccessTokenRefresh;
if (typeof refreshAccessTokenFunction !== 'function') {
return null;View on GitHub (pinned to 1f5dd2bbd2)
Solutions
- Set TWENTY_ACCESS_TOKEN (or TWENTY_API_KEY) in the environment.
- Or pass `token` explicitly: `new RestApiClient({ baseUrl, token })`.
- Ensure the token is non-empty after trimming.
- If running inside a Twenty front component, wire the host refresh API so the token is populated.
Example fix
// before
const client = new RestApiClient({ baseUrl });
// after
const client = new RestApiClient({ baseUrl, token: process.env.TWENTY_ACCESS_TOKEN! }); Defensive patterns
Strategy: validation
Validate before calling
const token =
options?.token ??
process.env[DEFAULT_APP_ACCESS_TOKEN_NAME] ??
process.env[DEFAULT_API_KEY_NAME];
if (!token || token.length === 0) {
throw new Error('Configure TWENTY_ACCESS_TOKEN or TWENTY_API_KEY');
}
const client = new RestApiClient({ baseUrl, token }); Type guard
const hasToken = (opts?: RestApiClientOptions): boolean => isDefined(opts?.token) && opts.token.length > 0;
Try / catch
try {
await client.get('/rest/objects/contact');
} catch (err) {
if (err instanceof RestApiClientError && err.message.includes('Missing application access token')) {
// provide a token via env or constructor
}
} Prevention
- Pass token explicitly rather than relying on env.
- Ensure TWENTY_ACCESS_TOKEN is in CI/serverless env.
- Wire front-component host refresh API to keep tokens fresh.
- Validate token presence at startup.
When it happens
Trigger: Constructing `new RestApiClient({ baseUrl })` without a token and calling any REST method without TWENTY_ACCESS_TOKEN or TWENTY_API_KEY in the environment.
Common situations: Missing TWENTY_ACCESS_TOKEN env var in CI/serverless; token option omitted and env not loaded; whitespace-only token value; loading the client before dotenv.config(); forgetting to pass the token in front-component hosts that lack env access.
Related errors
- Missing API url. Set the `${DEFAULT_API_URL_NAME}` environme
- Global `fetch` function is not available, pass a fetch imple
- ${caller}() requires the app runtime env vars ${DEFAULT_API_
- url or fetcher is required
- ${res.statusText}: ${await res.text()}
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/1353ba717bf73814.
Report an issue: GitHub.