jaegertracing/jaeger · error
invalid trace_id: %w
Error message
invalid trace_id: %w
What it means
buildQuery parses the user-supplied trace ID string with parseTraceID; a parse failure is wrapped as "invalid trace_id: <cause>". The MCP tool requires an exact, well-formed trace ID (e.g. 32 hex chars for a 128-bit ID) to query the trace store.
Source
Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_critical_path.go:99
return nil, types.GetCriticalPathOutput{}, fmt.Errorf("failed to compute critical path: %w", err)
}
// Build output
output := h.buildOutput(input.TraceID, trace, criticalPathSections)
return nil, output, nil
}
// buildQuery converts GetCriticalPathInput to querysvc.GetTraceParams.
func (*getCriticalPathHandler) buildQuery(input types.GetCriticalPathInput) (querysvc.GetTraceParams, error) {
// Validate input
if input.TraceID == "" {
return querysvc.GetTraceParams{}, errors.New("trace_id is required")
}
traceID, err := parseTraceID(input.TraceID)
if err != nil {
return querysvc.GetTraceParams{}, fmt.Errorf("invalid trace_id: %w", err)
}
return querysvc.GetTraceParams{
TraceIDs: []tracestore.GetTraceParams{
{TraceID: traceID},
},
RawTraces: false, // We want adjusted traces
}, nil
}
// buildOutput constructs the GetCriticalPathOutput from the trace and critical path sections.
func (*getCriticalPathHandler) buildOutput(
traceIDStr string,
trace ptrace.Traces,
criticalPathSections []criticalpath.Section,
) types.GetCriticalPathOutput {
// Build a map of spans for quick lookup
spanMap := jptrace.SpanMap(trace, func(span ptrace.Span) string {View on GitHub (pinned to 806f444784)
Solutions
- Pass the full 128-bit trace ID as lowercase hex (32 characters) from the trace's header, not a span ID or shortened form.
- Strip whitespace/quotes and any composite suffixes (e.g. ':spanid') from the ID.
- Re-copy the trace ID from the Jaeger UI or the storage record to avoid transcription errors.
Example fix
// before
{"trace_id": "abc123"}
// after
{"trace_id": "4e7a1f2b3c4d5e6f708192a3b4c5d6e7"} Defensive patterns
Strategy: validation
Validate before calling
func validTraceID(s string) bool {
s = strings.TrimSpace(s)
if len(s) != 32 && len(s) != 16 { return false }
_, err := hex.DecodeString(s)
return err == nil
}
if !validTraceID(input.TraceID) { return errors.New("trace_id must be 16 or 32 hex characters") } Type guard
func isHexString(s string, l int) bool {
return len(s) == l && strings.TrimFunc(strings.ToLower(s), func(r rune) bool {
return (r >= '0' && r <= '9') || (r >= 'a' && r <= 'f')
}) == ""
} Try / catch
out, err := handler.Handle(ctx, input)
if err != nil && strings.Contains(err.Error(), "invalid trace_id:") {
return fmt.Errorf("supply the full 32-char hex trace ID: %w", err)
} Prevention
- Copy trace IDs from the Jaeger UI's JSON/raw view, not the URL display string.
- For MCP/LLM callers, document that trace_id must be 32 lowercase hex characters.
- Trim and normalize IDs before sending them to the tool.
When it happens
Trigger: Calling the get_critical_path tool with a trace_id that is empty (a separate 'trace_id is required' error), non-hexadecimal, wrong length, or otherwise unparseable by parseTraceID.
Common situations: LLM/MCP client passes a display ID, span ID, or truncated trace ID copied from a UI; whitespace or URL-encoding artifacts in the string; passing a Jaeger 'traceid:spanid' composite string.
Related errors
- invalid trace_id: %w
- trace_id is required
- start_time must be before end_time
- trace_id is required
- span_ids is required and must not be empty
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/d3d348197634a5c9.
Report an issue: GitHub.