{"record":{"id":"f29c64559f26f2a8","repo":"cube-js/cube","slug":"can-t-fetch-metrics-from-dbt-cloud-res-errors-0","errorCode":null,"errorMessage":"Can't fetch metrics from Dbt Cloud: ${res.errors[0].message}","messagePattern":"Can't fetch metrics from Dbt Cloud: (.+?)","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-dbt-schema-extension/src/Dbt.ts","lineNumber":173,"sourceCode":"      const modelName = match[1];\n      metricDef.model = modelName.indexOf('.') !== -1 ? modelName : `model.${metricDef.package_name}.${modelName}`;\n    });\n    return this.loadMetricCubesFromNormalizedManifest(manifest, manifestPath, options);\n  }\n\n  public async loadMetricCubesFromDbtCloud(jobId: string | number, authToken: string, options: DbtLoadOptions): Promise<{ [cubeName: string]: any }> {\n    const response = await fetch('https://metadata.cloud.getdbt.com/graphql', {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Accept: 'application/json',\n        Authorization: `Bearer ${authToken}`\n      },\n      body: JSON.stringify({ query: loadModelsQuery, variables: { jobId } })\n    });\n    const res = <GraphqlResponse>(await response.json());\n    if (res.errors && res.errors.length > 0) {\n      throw new UserError(`Can't fetch metrics from Dbt Cloud: ${res.errors[0].message}`);\n    }\n    const manifest: DbtManifest = {\n      metrics: res.data.metrics.map(metricDef => ({\n        [metricDef.uniqueId]: {\n          unique_id: metricDef.uniqueId,\n          name: metricDef.name,\n          model: metricDef.model.uniqueId,\n          // eslint-disable-next-line camelcase\n          package_name: metricDef.packageName,\n          type: metricDef.type,\n          sql: metricDef.sql,\n          dimensions: metricDef.dimensions,\n          timestamp: metricDef.timestamp,\n        }\n      })).reduce((a, b) => ({ ...a, ...b }), {}),\n      nodes: res.data.models.map(modelDef => ({\n        [modelDef.uniqueId]: {\n          database: modelDef.database,","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-dbt-schema-extension/src/Dbt.ts#L155-L191","documentation":"loadMetricCubesFromDbtCloud executes a GraphQL query against the Dbt Cloud Discovery API (with a bearer token and jobId). If the response body contains a non-empty errors array, the first error message from the API is surfaced wrapped in this UserError.","triggerScenarios":"Calling loadMetricCubesFromDbtCloud with an invalid/expired Dbt Cloud API token, a jobId that doesn't exist or isn't accessible to the token, a GraphQL query error (e.g. metrics not exposed by the Discovery API for that job/account), or Dbt Cloud-side validation errors.","commonSituations":"Expired or rotated Dbt Cloud service tokens; wrong jobId in configuration; the job's environment lacking Discovery API access or the metrics feature; account/permission changes; Dbt Cloud API deprecations changing the schema the extension queries.","solutions":["Verify the Dbt Cloud auth token is valid and has access to the job/account (test with a curl to the Discovery API)","Check the jobId passed in options corresponds to an existing, successful job in the same account","Read the inner errors[0].message for the actual API reason (auth, not found, validation) and fix accordingly","Confirm the Dbt Cloud account/environment has the Discovery API/metrics enabled","Upgrade the extension if the Discovery API schema changed"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"const res = await fetch('https://cloud.getdbt.com/api/graphql/v2', {\n  method: 'POST',\n  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },\n  body: JSON.stringify({ query: 'query { __typename }' })\n});\nif (!res.ok) throw new Error(`Dbt Cloud token/jobId check failed: ${res.status}`);","typeGuard":"function hasGraphqlErrors(res) {\n  return Array.isArray(res?.errors) && res.errors.length > 0;\n}","tryCatchPattern":"try {\n  await dbt.loadMetricCubesFromDbtCloud(projectPath, { jobId, authToken });\n} catch (e) {\n  if (e.message.startsWith(\"Can't fetch metrics from Dbt Cloud\")) {\n    console.error('Dbt Cloud API error:', e.message); // inspect inner API message\n  } else { throw e; }\n}","preventionTips":["Rotate and validate service tokens before deployment","Verify jobId against the Dbt Cloud UI before configuring","Confirm Discovery API access for the job's environment","Wrap Dbt Cloud loads in retry-with-backoff for transient API issues"],"tags":["dbt","api","network","graphql","authentication"],"backgroundTag":"api-request-failed","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}