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

  1. Give each field a unique 'key' within its dataset.
  2. If two fields represent related data, rename one (e.g., 'name' and 'display_name').
  3. 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

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


AI-assisted analysis of lobehub/lobehub@10f24d7ade (2026-08-12). Data as JSON: /api/errors/876a5e88f24222d2. Report an issue: GitHub.