twentyhq/twenty · critical · RestApiClientError
Missing API url. Set the `${DEFAULT_API_URL_NAME}` environme
Error message
Missing API url. Set the `${DEFAULT_API_URL_NAME}` environment variable or pass `baseUrl` to `RestApiClient`. What it means
Thrown by RestApiClient.resolveBaseUrl (rest/index.ts:163-167) as a RestApiClientError when neither `baseUrl` was passed to the constructor nor the `TWENTY_API_URL` environment variable (DEFAULT_API_URL_NAME) is defined/non-empty. It is the entrypoint guard for every REST request, so the first call fails fast.
Source
Thrown at packages/twenty-client-sdk/src/rest/index.ts:164
patch<TResponse = unknown>(
path: string,
body?: unknown,
options?: RestApiRequestOptions,
) {
return this.execute<TResponse>('PATCH', path, body, options);
}
delete<TResponse = unknown>(path: string, options?: RestApiRequestOptions) {
return this.execute<TResponse>('DELETE', path, undefined, options);
}
private resolveBaseUrl(): string {
const baseUrl =
this.baseUrl ?? getProcessEnvironment()[DEFAULT_API_URL_NAME];
if (!isDefined(baseUrl) || baseUrl.trim().length === 0) {
throw new RestApiClientError(
`Missing API url. Set the \`${DEFAULT_API_URL_NAME}\` environment variable or pass \`baseUrl\` to \`RestApiClient\`.`,
);
}
return baseUrl.replace(/\/+$/, '');
}
private resolveFunctionsBaseUrl(): string | undefined {
const functionsBaseUrl =
getProcessEnvironment()[DEFAULT_FUNCTIONS_URL_NAME];
if (!isDefined(functionsBaseUrl) || functionsBaseUrl.trim().length === 0) {
return undefined;
}
return functionsBaseUrl.trim().replace(/\/+$/, '');
}
View on GitHub (pinned to 1f5dd2bbd2)
Solutions
- Set the TWENTY_API_URL environment variable to your Twenty instance (e.g. https://app.twenty.com).
- Or pass `baseUrl` explicitly: `new RestApiClient({ baseUrl: 'https://app.twenty.com' })`.
- If using dotenv, ensure dotenv.config() runs before constructing the client.
- Confirm the variable is exposed to the runtime (serverless/Container env).
Example fix
// before
const client = new RestApiClient();
// after
const client = new RestApiClient({ baseUrl: process.env.TWENTY_API_URL! }); Defensive patterns
Strategy: validation
Validate before calling
const baseUrl =
options?.baseUrl ?? process.env[DEFAULT_API_URL_NAME];
if (!baseUrl || baseUrl.trim().length === 0) {
throw new Error('Configure TWENTY_API_URL before constructing RestApiClient');
}
const client = new RestApiClient({ baseUrl }); Type guard
const hasBaseUrl = (opts?: RestApiClientOptions): boolean => isDefined(opts?.baseUrl) && opts.baseUrl.trim().length > 0;
Try / catch
try {
await client.get('/rest/objects/contact');
} catch (err) {
if (err instanceof RestApiClientError && err.message.includes('Missing API url')) {
// set TWENTY_API_URL or pass baseUrl
}
} Prevention
- Set TWENTY_API_URL in the deployment environment.
- Pass baseUrl explicitly in code to remove ambient dependency.
- Run dotenv.config() before instantiating the client.
- Add a startup check that the env var is present.
When it happens
Trigger: Constructing `new RestApiClient()` without a baseUrl and calling any method (get/post/put/patch/delete/request) without TWENTY_API_URL in the environment. resolveBaseUrl runs inside resolveTarget on every request.
Common situations: Forgot to set TWENTY_API_URL in .env; SSR/build environment missing the variable; typo in the env var name; loading the client before dotenv.config() ran; passing an empty/whitespace string as baseUrl.
Related errors
- Missing application access token. Set the `${DEFAULT_APP_ACC
- Global `fetch` function is not available, pass a fetch imple
- url or fetcher is required
- Global `fetch` function is not available, pass a fetch imple
- Request to ${url} failed with status ${response.status} ${re
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/54656f0b3ba5c48e.
Report an issue: GitHub.