cube-js/cube · critical

Cannot create CubeApi instance. Please check that the config

Error message

Cannot create CubeApi instance. Please check that the config is passed correctly and contains all required options.

What it means

The Angular client (cubejs-client-ngx) wraps the CubeApi instance behind a proxy class. When a method like load() is called, it lazily instantiates CubeApi via the `cube()` factory using config.token and config.options. If `cube()` returns a falsy value, the client throws this error because without a CubeApi instance no API calls can be made.

Source

Thrown at packages/cubejs-client-ngx/src/client.ts:42

  constructor(@Inject('config') private config: any | Observable<any>) {
    if (this.config instanceof Observable) {
      this.config.subscribe(() => {
        this.ready$.next(true);
      });
    } else {
      this.ready$.next(true);
    }
  }

  private apiInstance(): CubeApi {
    if (!this.cubeApi) {
      if (this.config instanceof Observable) {
        this.config.subscribe((config) => {
          this.cubeApi = cube(config.token, config.options);

          if (!this.cubeApi) {
            throw new Error(
              'Cannot create CubeApi instance. Please check that the config is passed correctly and contains all required options.'
            );
          }
        });
      } else {
        this.cubeApi = cube(this.config.token, this.config.options);
      }
    }

    return this.cubeApi;
  }

  public load(
    query: Query | Query[],
    options?: LoadMethodOptions
  ): Observable<ResultSet<any>> {
    return from(<Promise<ResultSet<any>>>this.apiInstance().load(query, options));
  }

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Ensure CubeClientModule.forRoot is called with { token, apiUrl } (or an Observable of that config) before injecting CubeClient.
  2. Verify the resolved config object has a non-empty `token` string and a valid `options` object.
  3. Check the `cube` factory injected via forRoot (custom DI) actually returns a CubeApi instance.
  4. Upgrade @cubejs-client/ngx and @cubejs-client/core to matching versions so the `cube` factory signature matches.

Example fix

// before
CubeClientModule.forRoot(null) // or missing forRoot
// after
CubeClientModule.forRoot({ token: 'CUBEJS_TOKEN', apiUrl: 'http://localhost:4000/cubejs-api/v1' })
Defensive patterns

Strategy: validation

Validate before calling

// before injecting / rendering
const cfg = { token: 'CUBEJS_TOKEN', apiUrl: 'http://localhost:4000/cubejs-api/v1' };
if (!cfg.token || !cfg.apiUrl) throw new Error('CubeClient config requires token and apiUrl');
CubeClientModule.forRoot(cfg);

Type guard

function hasCubeConfig(c: unknown): c is { token: string; options?: object } {
  return !!c && typeof c === 'object' && typeof (c as any).token === 'string' && (c as any).token.length > 0;
}

Try / catch

try {
  await client.load(query);
} catch (e) {
  if (e.message.includes('Cannot create CubeApi instance')) {
    console.error('CubeClient misconfigured: provide token/apiUrl via CubeClientModule.forRoot');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling load/sql/dryRun/meta/resultSet on CubeClient when `cube(config.token, config.options)` returns null/undefined — typically when the token or options passed to the config are malformed, or a custom/broken `cube` factory is injected via forRoot that returns nothing.

Common situations: Forgetting to call CubeClientModule.forRoot(...) with a valid token/apiUrl; passing a config object resolved from an Observable that yields an object missing `token`; injecting a stubbed cube factory in tests that returns undefined; using an outdated config shape where options/token keys were renamed.

Related errors


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