cube-js/cube · error · UserError
Expected reference to the model in format ref('model_name')
Error message
Expected reference to the model in format ref('model_name') but found '${metricDef.model}' What it means
Each metric in the dbt manifest must reference its underlying model via a model string in the exact format ref('model_name'). loadMetricCubesFromDbtProject matches metricDef.model against the regex /^ref\('(\S+)'\)$/ and throws this UserError when the string does not conform, since the model name cannot be extracted.
Source
Thrown at packages/cubejs-dbt-schema-extension/src/Dbt.ts:152
export class Dbt extends AbstractExtension {
public async loadMetricCubesFromDbtProject(projectPath: string, options: DbtLoadOptions): Promise<{ [cubeName: string]: any }> {
const dbtProjectPath = path.join(projectPath, 'dbt_project.yml');
if (!(await fs.pathExists(dbtProjectPath))) {
throw new UserError(`'${dbtProjectPath}' was not found. Please make sure '${projectPath}' is a path to the dbt project`);
}
// TODO read target path from dbt_project.yml
const manifestPath = path.join(projectPath, 'target', 'manifest.json');
if (!(await fs.pathExists(manifestPath))) {
throw new UserError(`'${manifestPath}' was not found. Please run 'dbt compile' in '${projectPath}'`);
}
const manifest = <DbtManifest>(await fs.readJSON(manifestPath));
Object.keys(manifest.metrics).forEach(metric => {
const regex = /^ref\('(\S+)'\)$/;
const metricDef = manifest.metrics[metric];
const match = metricDef.model.match(regex);
if (!match) {
throw new UserError(`Expected reference to the model in format ref('model_name') but found '${metricDef.model}'`);
}
// eslint-disable-next-line prefer-destructuring
const modelName = match[1];
metricDef.model = modelName.indexOf('.') !== -1 ? modelName : `model.${metricDef.package_name}.${modelName}`;
});
return this.loadMetricCubesFromNormalizedManifest(manifest, manifestPath, options);
}
public async loadMetricCubesFromDbtCloud(jobId: string | number, authToken: string, options: DbtLoadOptions): Promise<{ [cubeName: string]: any }> {
const response = await fetch('https://metadata.cloud.getdbt.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: `Bearer ${authToken}`
},
body: JSON.stringify({ query: loadModelsQuery, variables: { jobId } })
});View on GitHub (pinned to 7d981676b3)
Solutions
- Fix the metric definition in the dbt project so model uses ref('model_name') syntax and re-run dbt compile
- Check for quoting/whitespace issues: single quotes required inside ref(), no leading/trailing spaces
- Regenerate manifest.json with the same dbt CLI version rather than hand-editing it
- If tooling rewrites the manifest, ensure it preserves the ref('model_name') format
Example fix
// before (metric in manifest)
"model": "model.my_project.orders"
// after
"model": "ref('orders')" Defensive patterns
Strategy: validation
Validate before calling
for (const m of Object.values(manifest.metrics)) {
if (!/^ref\('(\S+)'\)$/.test(m.model)) {
throw new Error(`Metric ${m.name}: model must match ref('model_name'), got: ${m.model}`);
}
} Type guard
function hasRefModel(metricDef) {
return typeof metricDef.model === 'string' && /^ref\('(\S+)'\)$/.test(metricDef.model);
} Try / catch
try {
await dbt.loadMetricCubesFromDbtProject(projectPath, opts);
} catch (e) {
if (e.message.startsWith("Expected reference to the model")) {
console.error('Fix metric model refs in dbt project and re-run dbt compile:', e.message);
} else { throw e; }
} Prevention
- Always author metric model fields as ref('model_name') with single quotes
- Do not hand-edit manifest.json; regenerate via dbt compile
- Keep dbt CLI version consistent between environments
- Add a schema lint on metric definitions in dbt CI
When it happens
Trigger: A manifest metric's model field is e.g. 'model.my_project.my_model', a bare model name without ref(), uses double quotes ref("m"), contains extra spaces, or was produced by tooling that writes resolved model references instead of the ref() syntax.
Common situations: Manually editing or programmatically post-processing manifest.json before Cube reads it; older/newer dbt versions writing a different model reference format; third-party tooling that rewrites manifests; copy-pasting metric definitions with the wrong model syntax.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Model '${model}' is not found
- response.error
- Unsupported dbt metric type '${dbtMetricType}'
- '${dbtProjectPath}' was not found. Please make sure '${proje
- '${manifestPath}' was not found. Please run 'dbt compile' in
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/847fdf2702401ba0.
Report an issue: GitHub.