{"record":{"id":"876a5e88f24222d2","repo":"lobehub/lobehub","slug":"datasets-datasetindex-field-keys-must-be-uniqu","errorCode":null,"errorMessage":"datasets[${datasetIndex}] field keys must be unique","messagePattern":"datasets\\[(.+?)\\] field keys must be unique","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/cli/src/commands/verifyHelpers.ts","lineNumber":334,"sourceCode":"    }\n\n    const fields = dataset.fields.map((rawField, fieldIndex) => {\n      const field = objectValue(rawField);\n      const key = firstString(field?.key);\n      const type = field?.type;\n      if (!key || typeof type !== 'string' || !VISUALIZATION_FIELD_TYPES.has(type)) {\n        throw new Error(`datasets[${datasetIndex}].fields[${fieldIndex}] is invalid`);\n      }\n      return {\n        key,\n        label: firstString(field.label),\n        type,\n        unit: firstString(field.unit),\n      } as VerifyVisualizationField;\n    });\n    const fieldKeys = new Set(fields.map((field) => field.key));\n    if (fieldKeys.size !== fields.length) {\n      throw new Error(`datasets[${datasetIndex}] field keys must be unique`);\n    }\n\n    const rows = dataset.rows.map((rawRow, rowIndex) => {\n      const row = objectValue(rawRow);\n      if (\n        !row ||\n        Object.entries(row).some(([key, cell]) => !fieldKeys.has(key) || !visualizationValue(cell))\n      ) {\n        throw new Error(`datasets[${datasetIndex}].rows[${rowIndex}] does not match its fields`);\n      }\n      return row as Record<string, VerifyVisualizationValue>;\n    });\n    rowCount += rows.length;\n    return { fields, id, rows } satisfies VerifyVisualizationDataset;\n  });\n\n  if (rowCount > MAX_INLINE_VISUALIZATION_ROWS) {\n    throw new Error(`visualization metadata exceeds ${MAX_INLINE_VISUALIZATION_ROWS} inline rows`);","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/lobehub/lobehub/blob/10f24d7ade75139093a9373b364f6bc91f3cd7db/apps/cli/src/commands/verifyHelpers.ts#L316-L352","documentation":"Thrown after building a Set of field keys for one dataset: if the Set size is smaller than the fields array length, two fields share the same key. Duplicate keys would make row cells ambiguous, so the dataset is rejected.","triggerScenarios":"Two entries in datasets[i].fields share the same 'key' string (e.g., two fields both keyed 'name').","commonSituations":"Copy-pasted field descriptors not renamed; case-only duplicates like 'Id' and 'id' that look distinct to a human but here are treated as distinct (note: this check is case-sensitive, so those pass — real exact-match duplicates fail).","solutions":["Give each field a unique 'key' within its dataset.","If two fields represent related data, rename one (e.g., 'name' and 'display_name').","Re-run after removing the duplicate descriptor."],"exampleFix":"// before\nfields: [{ key: 'name', type: 'string' }, { key: 'name', type: 'string' }]\n// after\nfields: [{ key: 'first_name', type: 'string' }, { key: 'last_name', type: 'string' }]","handlingStrategy":"validation","validationCode":"function checkUniqueKeys(fields: { key: string }[]): boolean {\n  return new Set(fields.map(f => f.key)).size === fields.length;\n}","typeGuard":null,"tryCatchPattern":"try { visualizationMetadata(value); } catch (e) { if (e instanceof Error && /field keys must be unique/.test(e.message)) { /* dedupe fields */ } throw e; }","preventionTips":["Generate field keys from a single source of truth (schema columns) to avoid divergence.","Add a unit test asserting unique keys when constructing datasets programmatically."],"tags":["cli","verify","visualization","validation"],"backgroundTag":null,"analyzedSha":"10f24d7ade75139093a9373b364f6bc91f3cd7db","analyzedAt":"2026-08-12T11:43:19.543Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}