JuliusBrussee/caveman · error
mapped trace_id is empty
Error message
mapped trace_id is empty
What it means
After mapping, mapGeneric verifies the resolved TraceID is non-empty after TrimSpace. This triggers when the source path WAS found but its value was empty, whitespace, or converted to an empty string by asString. It is distinct from error 1182 (path not found): here the path resolved but produced no usable identifier.
Source
Thrown at shared/platform/importers/generic.go:159
case "string":
assignString(&sp, target, asString(val))
case "int":
assignInt(&sp, target, parseFlexInt(val))
case "float":
sp.TotalCostUSD = roundUSD(parseFlexFloat(val))
case "time":
s, ns := parseTimeFlexible(val)
if target == "timestamp" {
sp.Timestamp = s
startNs = ns
} else {
sp.EndTimestamp = s
endNs = ns
}
}
}
if strings.TrimSpace(sp.TraceID) == "" {
return Span{}, nil, fmt.Errorf("mapped trace_id is empty")
}
if strings.TrimSpace(sp.SpanID) == "" {
return Span{}, nil, fmt.Errorf("mapped span_id is empty")
}
if sp.Timestamp == "" {
return Span{}, nil, fmt.Errorf("mapped timestamp is missing or invalid")
}
if d := durationMS(startNs, endNs); d > 0 {
sp.DurationMS = d
}
sp.Attributes = map[string]string{"import.source": "generic"}
applyScope(&sp, opts)
return sp, resolved, nil
}
func assignString(sp *Span, target, v string) {
switch target {
case "trace_id":View on GitHub (pinned to 27d5a3981a)
Solutions
- Find the offending record (it is the one at the failing position) and either populate a real trace ID upstream or drop it
- If the field is sometimes empty, pre-process the data to synthesize a deterministic trace ID before import
- Double-check the mapping does not point at a sibling field that is frequently empty
- Treat empty trace/span IDs as data-quality defects at the source system, not importer configuration
Example fix
// before
rec := map[string]any{"traceId": "", "spanId": "s1", "started_at": "2026-01-01T00:00:00Z"}
// after
rec := map[string]any{"traceId": "gen-trace-1", "spanId": "s1", "started_at": "2026-01-01T00:00:00Z"} Defensive patterns
Strategy: validation
Validate before calling
func hasNonEmptyTraceID(rec map[string]any, path string) bool {
v, ok := lookupPath(rec, path)
if !ok { return false }
s, ok := v.(string)
return ok && strings.TrimSpace(s) != ""
} Type guard
func isUsableID(v any) bool {
s, ok := v.(string)
return ok && strings.TrimSpace(s) != ""
} Try / catch
if strings.Contains(err.Error(), "trace_id is empty") { /* identify and drop/synthesize IDs for offending records */ } Prevention
- Pre-scan records and synthesize deterministic trace IDs where empty (e.g. hash of record)
- Treat empty identifiers as export defects; alert on them in the source pipeline
- Never map trace_id to a field that is optional in the source schema
When it happens
Trigger: Records where the trace-id field exists but is "" or " "; a null JSON value that asString renders as empty; a numeric 0 or false in the trace-id field being stringified into something empty; mapping trace_id to a path that resolves to an object/array.
Common situations: Vendor exports that emit empty trace IDs for rootless/system spans; records from a pre-migration system that did not set trace IDs; mapping trace_id to the wrong field that is usually populated but empty on summary rows.
Related errors
- mapped span_id is empty
- generic import requires a %q mapping
- generic decode: expected a JSON array or {"data":[...]} of o
- mapped source path %q for required target %q was not found
- mapped timestamp is missing or invalid
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/1e991645c95678cd.
Report an issue: GitHub.