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
- Set field.type to one of: boolean, category, number, string, temporal.
- Provide a non-empty string field.key.
- 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
- Keep a literal union type for field.type so the compiler catches typos.
- Document the alias mapping (integer→number, date→temporal) next to your data-export code.
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
- ${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/ab362660487ec41d.
Report an issue: GitHub.