lobehub/lobehub · error · Error
datasets[${datasetIndex}] field keys must be unique
Error message
datasets[${datasetIndex}] field keys must be unique What it means
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.
Source
Thrown at apps/cli/src/commands/verifyHelpers.ts:334
}
const fields = dataset.fields.map((rawField, fieldIndex) => {
const field = objectValue(rawField);
const key = firstString(field?.key);
const type = field?.type;
if (!key || typeof type !== 'string' || !VISUALIZATION_FIELD_TYPES.has(type)) {
throw new Error(`datasets[${datasetIndex}].fields[${fieldIndex}] is invalid`);
}
return {
key,
label: firstString(field.label),
type,
unit: firstString(field.unit),
} as VerifyVisualizationField;
});
const fieldKeys = new Set(fields.map((field) => field.key));
if (fieldKeys.size !== fields.length) {
throw new Error(`datasets[${datasetIndex}] field keys must be unique`);
}
const rows = dataset.rows.map((rawRow, rowIndex) => {
const row = objectValue(rawRow);
if (
!row ||
Object.entries(row).some(([key, cell]) => !fieldKeys.has(key) || !visualizationValue(cell))
) {
throw new Error(`datasets[${datasetIndex}].rows[${rowIndex}] does not match its fields`);
}
return row as Record<string, VerifyVisualizationValue>;
});
rowCount += rows.length;
return { fields, id, rows } satisfies VerifyVisualizationDataset;
});
if (rowCount > MAX_INLINE_VISUALIZATION_ROWS) {
throw new Error(`visualization metadata exceeds ${MAX_INLINE_VISUALIZATION_ROWS} inline rows`);View on GitHub (pinned to 10f24d7ade)
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.
Example fix
// before
fields: [{ key: 'name', type: 'string' }, { key: 'name', type: 'string' }]
// after
fields: [{ key: 'first_name', type: 'string' }, { key: 'last_name', type: 'string' }] Defensive patterns
Strategy: validation
Validate before calling
function checkUniqueKeys(fields: { key: string }[]): boolean {
return new Set(fields.map(f => f.key)).size === fields.length;
} Try / catch
try { visualizationMetadata(value); } catch (e) { if (e instanceof Error && /field keys must be unique/.test(e.message)) { /* dedupe fields */ } throw e; } Prevention
- 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.
When it happens
Trigger: Two entries in datasets[i].fields share the same 'key' string (e.g., two fields both keyed 'name').
Common situations: 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).
Related errors
- ${path}.${key} must reference a declared dataset field
- ${path}.${key} must be a non-empty string
- ${path}.series must be a non-empty array
- ${seriesPath} must be an object
- ${seriesPath}.label must be a non-empty string
AI-assisted analysis of lobehub/lobehub@10f24d7ade (2026-08-12).
Data as JSON: /api/errors/876a5e88f24222d2.
Report an issue: GitHub.