lobehub/lobehub · error · Error

datasets[${datasetIndex}].fields[${fieldIndex}] is invalid

Error message

datasets[${datasetIndex}].fields[${fieldIndex}] is invalid

What it means

Thrown while mapping dataset.fields when a field descriptor is invalid: key missing/empty/non-string, type not a string, or type not in the allowed set {boolean, category, number, string, temporal}. The allowed set is the VISUALIZATION_FIELD_TYPES whitelist that the report viewer knows how to render.

Source

Thrown at apps/cli/src/commands/verifyHelpers.ts:323

    return undefined;
  if (!Array.isArray(input.datasets) || !Array.isArray(input.visualizations)) {
    throw new Error('datasets and visualizations must both be arrays');
  }

  let rowCount = 0;
  const datasets = input.datasets.map((rawDataset, datasetIndex) => {
    const dataset = objectValue(rawDataset);
    const id = firstString(dataset?.id);
    if (!id || !Array.isArray(dataset?.fields) || !Array.isArray(dataset.rows)) {
      throw new Error(`datasets[${datasetIndex}] needs id, fields, and rows`);
    }

    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))

View on GitHub (pinned to 10f24d7ade)

Solutions

  1. Set field.type to one of: boolean, category, number, string, temporal.
  2. Provide a non-empty string field.key.
  3. Map common aliases: integer/float/double → number; date/datetime/timestamp → temporal; enum → category.

Example fix

// before
{ key: 'age', type: 'integer' }
// after
{ key: 'age', type: 'number' }
Defensive patterns

Strategy: validation

Validate before calling

const FIELD_TYPES = new Set(['boolean','category','number','string','temporal']);
function validField(f: unknown): boolean {
  return !!f && typeof f === 'object' && typeof (f as any).key === 'string' && (f as any).key.length > 0 && typeof (f as any).type === 'string' && FIELD_TYPES.has((f as any).type);
}

Type guard

function isFieldDescriptor(v: unknown): v is { key: string; type: 'boolean'|'category'|'number'|'string'|'temporal' } {
  return !!v && typeof v === 'object' && typeof (v as any).key === 'string' && FIELD_TYPES.has((v as any).type);
}

Try / catch

try { visualizationMetadata(value); } catch (e) { if (e instanceof Error && /fields\[\d+\] is invalid/.test(e.message)) { /* show allowed types to author */ } throw e; }

Prevention

When it happens

Trigger: datasets[i].fields[j] has no key, a numeric type, or a type like 'int'/'float'/'datetime' not in the whitelist.

Common situations: Author writes type: 'integer' instead of 'number'; type: 'date' instead of 'temporal'; key omitted because the field was auto-generated.

Related errors


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