{"record":{"id":"a22e698c8016918d","repo":"cube-js/cube","slug":"the-apiurl-option-is-required","errorCode":null,"errorMessage":"The `apiUrl` option is required","messagePattern":"The `apiUrl` option is required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cubejs-client-core/src/index.ts","lineNumber":276,"sourceCode":"   * ```js\n   * import cube from '@cubejs-client/core';\n   * const cubeApi = cube(\n   *   async () => await Auth.getJwtToken(),\n   *   { apiUrl: 'http://localhost:4000/cubejs-api/v1' }\n   * );\n   * ```\n   */\n  public constructor(\n    apiToken: string | (() => Promise<string>) | undefined | CubeApiOptions,\n    options?: CubeApiOptions\n  ) {\n    if (apiToken && !Array.isArray(apiToken) && typeof apiToken === 'object') {\n      options = apiToken;\n      apiToken = undefined;\n    }\n\n    if (!options || (!options.transport && !options.apiUrl)) {\n      throw new Error('The `apiUrl` option is required');\n    }\n\n    this.apiToken = apiToken;\n    this.apiUrl = options.apiUrl;\n    this.method = options.method;\n    this.headers = options.headers || {};\n    this.credentials = options.credentials;\n\n    this.transport = options.transport || new HttpTransport({\n      authorization: typeof apiToken === 'string' ? apiToken : undefined,\n      apiUrl: this.apiUrl,\n      method: this.method,\n      headers: this.headers,\n      credentials: this.credentials,\n      fetchTimeout: options.fetchTimeout,\n      signal: options.signal\n    });\n","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-client-core/src/index.ts#L258-L294","documentation":"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.","triggerScenarios":"new CubejsClient(apiToken) or new CubejsClient() with no options object, or an options object that has neither apiUrl nor transport set.","commonSituations":"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.","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)"],"exampleFix":"// before\nconst client = new CubejsClient(token);\n// after\nconst client = new CubejsClient({ apiToken: token, apiUrl: 'https://cube.example.com/cubejs-api/v1' });","handlingStrategy":"validation","validationCode":"if (!apiUrl && !transport) throw new Error('Provide apiUrl or transport before creating CubejsClient');\nconst client = new CubejsClient({ apiToken, apiUrl });","typeGuard":"function hasClientConfig(opts) {\n  return !!opts && (typeof opts.apiUrl === 'string' || !!opts.transport);\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["configuration","client-constructor","validation"],"backgroundTag":"missing-required-option","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}