cube-js/cube · error
The `apiUrl` option is required
Error message
The `apiUrl` option is required
What it means
CubejsClient requires either a transport instance or an apiUrl option to know where to send queries. The constructor throws immediately if neither is provided, since no API requests can be routed. This is a fail-fast configuration validation.
Source
Thrown at packages/cubejs-client-core/src/index.ts:276
* ```js
* import cube from '@cubejs-client/core';
* const cubeApi = cube(
* async () => await Auth.getJwtToken(),
* { apiUrl: 'http://localhost:4000/cubejs-api/v1' }
* );
* ```
*/
public constructor(
apiToken: string | (() => Promise<string>) | undefined | CubeApiOptions,
options?: CubeApiOptions
) {
if (apiToken && !Array.isArray(apiToken) && typeof apiToken === 'object') {
options = apiToken;
apiToken = undefined;
}
if (!options || (!options.transport && !options.apiUrl)) {
throw new Error('The `apiUrl` option is required');
}
this.apiToken = apiToken;
this.apiUrl = options.apiUrl;
this.method = options.method;
this.headers = options.headers || {};
this.credentials = options.credentials;
this.transport = options.transport || new HttpTransport({
authorization: typeof apiToken === 'string' ? apiToken : undefined,
apiUrl: this.apiUrl,
method: this.method,
headers: this.headers,
credentials: this.credentials,
fetchTimeout: options.fetchTimeout,
signal: options.signal
});
View on GitHub (pinned to 7d981676b3)
Solutions
- Pass apiUrl in options: new CubejsClient({ apiUrl: 'https://cube.example.com/cubejs-api/v1', apiToken: token })
- If you use a custom transport, pass transport instead of apiUrl (or alongside apiUrl)
- Verify the options object is actually reaching the constructor (not undefined due to a spread/conditional bug)
Example fix
// before
const client = new CubejsClient(token);
// after
const client = new CubejsClient({ apiToken: token, apiUrl: 'https://cube.example.com/cubejs-api/v1' }); Defensive patterns
Strategy: validation
Validate before calling
if (!apiUrl && !transport) throw new Error('Provide apiUrl or transport before creating CubejsClient');
const client = new CubejsClient({ apiToken, apiUrl }); Type guard
function hasClientConfig(opts) {
return !!opts && (typeof opts.apiUrl === 'string' || !!opts.transport);
} Prevention
- Always construct the client from a config factory that asserts apiUrl exists
- Read env config before client initialization
- Keep a single shared client instance with validated config
When it happens
Trigger: new CubejsClient(apiToken) or new CubejsClient() with no options object, or an options object that has neither apiUrl nor transport set.
Common situations: Forgetting to pass options when only a token is available; renaming apiUrl to api-url or baseUrl; constructing the client before async config (env vars) loads; passing an empty object.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- A user-defined contextToApiScopes function returns a wrong s
- Value "${input}" is not valid for ${envName}. ${description}
- Value "${input}" is not valid for ${envName}. Should be a po
- Value "${input}" is not valid for ${envName}. Should be lowe
- Value "${value}" is not valid for CUBEJS_MAX_REQUEST_SIZE. M
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/a22e698c8016918d.
Report an issue: GitHub.