{"record":{"id":"1e5a95889bb7e05e","repo":"cube-js/cube","slug":"ungrouped-query-requires-primary-keys-to-be-presen","errorCode":null,"errorMessage":"Ungrouped query requires primary keys to be present in dimensions: ${missingPrimaryKeys.map(k => `'${k}'`).join(', ')}. Pass allowUngroupedWithoutPrimaryKey option to disable this check.","messagePattern":"Ungrouped query requires primary keys to be present in dimensions: (.+?)'`\\)\\.join\\(', '\\)\\}\\. Pass allowUngroupedWithoutPrimaryKey option to disable this check\\.","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/adapter/BaseQuery.js","lineNumber":622,"sourceCode":"    return R.fromPairs(\n      this.measures.map(m => [m.unescapedAliasName(), m.measure]).concat(\n        this.dimensions.map(m => [m.unescapedAliasName(), m.dimension])\n      ).concat(\n        this.timeDimensions.filter(m => !!m.granularity)\n          .map(m => [m.unescapedAliasName(), `${m.dimension}.${m.granularity}`])\n      )\n    );\n  }\n\n  initUngrouped() {\n    this.ungrouped = this.options.ungrouped;\n    if (this.ungrouped) {\n      if (!this.options.allowUngroupedWithoutPrimaryKey && this.join) {\n        const cubes = R.uniq([this.join.root].concat(this.join.joins.map(j => j.originalTo)));\n        const primaryKeyNames = cubes.flatMap(c => this.primaryKeyNames(c));\n        const missingPrimaryKeys = primaryKeyNames.filter(key => !this.dimensions.find(d => d.dimension === key));\n        if (missingPrimaryKeys.length) {\n          throw new UserError(`Ungrouped query requires primary keys to be present in dimensions: ${missingPrimaryKeys.map(k => `'${k}'`).join(', ')}. Pass allowUngroupedWithoutPrimaryKey option to disable this check.`);\n        }\n      }\n      if (this.measureFilters.length) {\n        throw new UserError('Measure filters aren\\'t allowed in ungrouped query');\n      }\n    }\n  }\n\n  get subQueryDimensions() {\n    // eslint-disable-next-line no-underscore-dangle\n    if (!this._subQueryDimensions) {\n      // eslint-disable-next-line no-underscore-dangle\n      this._subQueryDimensions = this.collectFromMembers(\n        false,\n        this.collectSubQueryDimensionsFor.bind(this),\n        'collectSubQueryDimensionsFor'\n      );\n    }","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js#L604-L640","documentation":"In ungrouped (raw rows) queries Cube does not aggregate, so it requires that the primary key of every joined cube is present among the dimensions — otherwise rows cannot be uniquely identified and results may be wrong or duplicated. When required primary keys are missing and allowUngroupedWithoutPrimaryKey is not set, it throws this UserError.","triggerScenarios":"Running a query with ungrouped mode (e.g. using the raw/ungrouped option or row-level queries) whose join involves cubes whose primary keys are not included in the dimensions list.","commonSituations":"Building record-detail/drill-down endpoints that select joined cube members but forget to include id dimensions; adding a join to an existing ungrouped query.","solutions":["Add each listed missing primary key (e.g. 'Orders.id') to the query dimensions","Set allowUngroupedWithoutPrimaryKey: true in query options to bypass the check (accepting the risk)","Remove unnecessary joins so fewer primary keys are required"],"exampleFix":"// before\ndimensions: ['Orders.status'], ungrouped: true, joins: [Users]\n// after\ndimensions: ['Orders.status', 'Users.id'], ungrouped: true","handlingStrategy":"validation","validationCode":"function ensureUngroupedPrimaryKeys(query, primaryKeyOf) {\n  if (!query.ungrouped) return;\n  const cubes = joinedCubesOf(query); // from joins + dimensions\n  const missing = cubes\n    .map(c => primaryKeyOf(c))\n    .filter(pk => !query.dimensions.includes(pk));\n  if (missing.length && !query.allowUngroupedWithoutPrimaryKey) {\n    query.dimensions.push(...missing);\n  }\n}\nensureUngroupedPrimaryKeys(query, pkIndex);","typeGuard":null,"tryCatchPattern":"try {\n  await cubeApi.load(query);\n} catch (e) {\n  if (/Ungrouped query requires primary keys/.test(e.message)) {\n    const missing = /dimensions: (.+)\\./.exec(e.message)[1].split(', ');\n    query.dimensions.push(...missing);\n    return cubeApi.load(query);\n  }\n  throw e;\n}","preventionTips":["Always include the id dimension of each joined cube in ungrouped queries","Or pass allowUngroupedWithoutPrimaryKey explicitly when you accept the risk","Re-check ungrouped queries whenever a join is added"],"tags":["ungrouped","primary-key","validation"],"backgroundTag":"ungrouped-query-missing-primary-key","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}