JuliusBrussee/caveman · error
generic record %d: %w
Error message
generic record %d: %w
What it means
Thrown by the generic importer (shared/platform/importers/generic.go:75) when mapGeneric fails converting the i-th record (records are 1-based in the message) into a Span. The underlying cause is in the wrapped error: typically a source field mapped to a Span column has the wrong type or cannot be coerced. Like the JSONL importer, one bad record aborts the entire import.
Source
Thrown at shared/platform/importers/generic.go:75
func parseGeneric(data []byte, opts Options) ([]Span, error) {
if err := validateGenericFieldMap(opts.FieldMap); err != nil {
return nil, err
}
records, err := decodeGenericRecords(data)
if err != nil {
return nil, err
}
if len(records) == 0 {
return []Span{}, nil
}
rows := make([]Span, 0, len(records))
resolvedTargets := make(map[string]bool, len(opts.FieldMap))
for i, rec := range records {
sp, resolved, err := mapGeneric(rec, opts)
if err != nil {
return nil, fmt.Errorf("generic record %d: %w", i+1, err)
}
for target := range resolved {
resolvedTargets[target] = true
}
rows = append(rows, sp)
}
for target, path := range opts.FieldMap {
if !resolvedTargets[target] {
return nil, fmt.Errorf("mapped source path %q for target %q was not found in any record", path, target)
}
}
return rows, nil
}
func validateGenericFieldMap(fieldMap map[string]string) error {
if len(fieldMap) == 0 {
return fmt.Errorf("generic import requires a non-empty field map")
}View on GitHub (pinned to 27d5a3981a)
Solutions
- Read the wrapped error - it names the failing field and record; inspect that record directly.
- Normalize the offending values at the source or in the FieldMap (map a different, consistently-typed source path).
- Drop or quarantine rows that cannot conform (in your own pre-processing), then re-import.
- For heterogeneous timestamps, pre-convert them to RFC3339 in the source file.
Defensive patterns
Strategy: try-catch
Validate before calling
// dry-run the first record through the same mapping before the batch
if len(records) > 0 {
if _, _, err := mapGenericRecord(records[0], opts); err != nil {
return fmt.Errorf("field map incompatible with sample record: %w", err)
}
} Try / catch
rows, err := importers.ImportGeneric(data, opts)
if err != nil {
return fmt.Errorf("generic import failed at the record named in the error; nothing ingested: %w", err)
} Prevention
- Test the field map against a sample of real records before full imports.
- Normalize timestamps to RFC3339 and IDs to strings in the source export.
- Watch for type drift in CSV columns (empty cells, thousands separators).
When it happens
Trigger: Calling the generic import with a FieldMap and a dataset where, in record N, a mapped path resolves to a value incompatible with its target column - e.g. timestamp mapped to a plain string 'yesterday', or span_id mapped to a number where a string is required. The wrapped error says which field and why.
Common situations: CSV/JSON exports where a column's type drifts between rows (empty cell parsed as null, numbers formatted with thousands separators); timestamps in a non-supported format; schema evolution in the source system adding new formats; trailing summary rows in reports.
Related errors
- caveman-jsonl line %d: %w
- mapped source path %q for target %q was not found in any rec
- generic import requires a non-empty field map
- unknown target column %q (not a caveman.spans column)
- generic target %q requires a non-empty source path
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/24345fb51827fd1d.
Report an issue: GitHub.