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

  1. Pass apiUrl in options: new CubejsClient({ apiUrl: 'https://cube.example.com/cubejs-api/v1', apiToken: token })
  2. If you use a custom transport, pass transport instead of apiUrl (or alongside apiUrl)
  3. 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

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


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/a22e698c8016918d. Report an issue: GitHub.