JuliusBrussee/caveman · error

mapped source path %q for target %q was not found in any rec

Error message

mapped source path %q for target %q was not found in any record

What it means

Thrown by the generic importer (generic.go:84) after all records were converted: some target in the FieldMap was never resolved by any record's mapped source path. The design refuses a mapping that silently produces empty columns - every declared target must be found at least once, or the whole import fails. The message names both the source path and the target.

Source

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

	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")
	}
	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"} {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Check the exact path in the error against a real record: jq '.[0]' or head -1 of the source.
  2. Fix the path spelling/nesting/case in the FieldMap to match the data.
  3. If the target is genuinely absent from the source, remove it from the FieldMap - optional columns must not be declared.
  4. Re-run; the check passes only when every mapped path resolves in at least one record.

Example fix

# before
fieldMap = {"trace_id": "ctx.traceID", ...}   # data uses ctx.trace_id

# after
fieldMap = {"trace_id": "ctx.trace_id", ...}
Defensive patterns

Strategy: validation

Validate before calling

// every mapped path must resolve in at least one sample record
resolved := map[string]bool{}
for _, rec := range sample {
    for target, path := range fieldMap {
        if _, ok := lookupPath(rec, path); ok { resolved[target] = true }
    }
}
for target, path := range fieldMap {
    if !resolved[target] { return fmt.Errorf("path %q never resolves; fix field map", path) }
}

Try / catch

if _, err := importers.ImportGeneric(data, opts); err != nil {
    return err // path/target in the message tells you which mapping is stale
}

Prevention

When it happens

Trigger: FieldMap maps target 'trace_id' to path 'ctx.trace' but no record in the dataset contains that path (typo in the path, renamed key in the source, or case mismatch), so resolvedTargets never gains 'trace_id' and the post-loop check fires.

Common situations: Field map written against documentation that drifted from the actual export; nested-path syntax wrong (e.g. 'traceId' vs 'trace_id', or missing a nesting level); source switched from flat to nested JSON; a sample-based map applied to a differently-shaped full export.

Related errors


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