JuliusBrussee/caveman · error

generic import requires a non-empty field map

Error message

generic import requires a non-empty field map

What it means

Thrown by validateGenericFieldMap (generic.go:92): the generic importer was invoked with an empty (or nil) FieldMap. The field map is the entire definition of a generic import - it says which source path fills which caveman.spans column - so without it there is nothing to import and the call is refused up front, before any data is read.

Source

Thrown at shared/platform/importers/generic.go:92

		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")
	}
	for target, path := range fieldMap {
		if _, ok := genericTargets[target]; !ok {
			return fmt.Errorf("unknown target column %q (not a caveman.spans column)", target)
		}
		if strings.TrimSpace(path) == "" {
			return fmt.Errorf("generic target %q requires a non-empty source path", target)
		}
	}
	for _, target := range []string{"trace_id", "span_id", "timestamp"} {
		if _, ok := fieldMap[target]; !ok {
			return fmt.Errorf("generic import requires a %q mapping", target)
		}
	}
	return nil
}

func decodeGenericRecords(data []byte) ([]map[string]any, error) {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Populate Options.FieldMap with at least trace_id, span_id, and timestamp mappings (those are mandatory anyway).
  2. Verify the config key spelling/casing that deserializes into FieldMap.
  3. Fail fast at your call site when the map is empty, before invoking the importer.
  4. See the genericTargets set in the same file for valid target names.

Example fix

// before
opts := importers.Options{} // FieldMap nil

// after
opts := importers.Options{FieldMap: map[string]string{
  "trace_id": "ctx.trace_id",
  "span_id":  "ctx.span_id",
  "timestamp":"ts",
}}
Defensive patterns

Strategy: validation

Validate before calling

if len(fieldMap) == 0 {
    return errors.New("refusing generic import: field map is empty")
}

Type guard

func isUsableFieldMap(m map[string]string) bool {
    if len(m) == 0 { return false }
    for _, t := range []string{"trace_id", "span_id", "timestamp"} {
        if _, ok := m[t]; !ok { return false }
    }
    return true
}

Try / catch

if err := importers.ImportGeneric(data, opts); err != nil {
    return fmt.Errorf("import misconfigured: %w", err)
}

Prevention

When it happens

Trigger: Constructing the generic import Options with FieldMap omitted, initialized as an empty map, or zeroed by a struct literal that forgets the field; also when a JSON/YAML config deserializes to an empty map because the key was misspelled.

Common situations: A new caller wiring the importer by copying a struct literal and dropping the map; configuration loaded from a file where 'fieldmap' vs 'field_map' key casing mismatched and unmarshalling silently left it empty; conditional code paths that build the map only in one branch.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/50ac273eadb665c7. Report an issue: GitHub.