jaegertracing/jaeger · error
trace_id is required
Error message
trace_id is required
What it means
buildQuery validates the GetTraceTopologyInput before converting it to querysvc.GetTraceParams. Since a topology cannot be computed without a trace, an empty TraceID string is rejected immediately with "trace_id is required". This is a plain input-validation error raised before any storage call is made.
Source
Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_trace_topology.go:110
if !traceFound {
return nil, types.GetTraceTopologyOutput{}, errors.New("trace not found")
}
// Build the flat topology list from the collected spans
output := types.GetTraceTopologyOutput{
TraceID: input.TraceID,
Spans: h.buildFlatTopology(spans, input.Depth),
}
return nil, output, nil
}
// buildQuery converts GetTraceTopologyInput to querysvc.GetTraceParams.
func (*getTraceTopologyHandler) buildQuery(input types.GetTraceTopologyInput) (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
}
// extractRawSpan extracts minimal span information needed for topology.
func extractRawSpan(pos jptrace.SpanIterPos, span ptrace.Span) rawSpan {
// Get service name from resource attributesView on GitHub (pinned to 806f444784)
Solutions
- Set the trace_id argument on the get_trace_topology call to a non-empty trace ID.
- If the ID comes from a prior tool call or pipeline step, check that step actually produced it before calling this tool.
- Check the JSON key casing in the request payload (trace_id vs TraceID) so it unmarshals into the TraceID field.
Example fix
// before
input := types.GetTraceTopologyInput{} // TraceID empty
// after
if input.TraceID == "" {
return fmt.Errorf("get_trace_topology: trace_id must be provided")
}
input := types.GetTraceTopologyInput{TraceID: traceIDFromParentStep} Defensive patterns
Strategy: validation
Validate before calling
if input.TraceID == "" {
return errors.New("get_trace_topology: trace_id is required")
} Type guard
func hasTraceID(in types.GetTraceTopologyInput) bool { return in.TraceID != "" } Try / catch
out, err := handler.Handle(ctx, in)
if err != nil {
if strings.Contains(err.Error(), "trace_id is required") {
return fmt.Errorf("caller bug: GetTraceTopologyInput.TraceID was not set: %w", err)
}
return err
} Prevention
- Construct inputs with explicit field names, never positional/zero-value literals.
- Make the upstream step that produces the trace ID return an error when it has none.
- Use JSON key casing consistent with the Go field tags (trace_id) in payloads.
When it happens
Trigger: Invoking the get_trace_topology MCP handler with a GetTraceTopologyInput whose TraceID field is the empty string (field omitted, JSON key misspelled so it unmarshals to zero value, or the caller passed an unset variable).
Common situations: MCP clients omitting the trace_id argument; constructing the input struct programmatically and forgetting to set TraceID; an upstream step that failed silently and left the ID blank.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- start_time_max must be after start_time_min
- duration_max must be greater than duration_min
- trace not found
- trace_id is required
- start_time must be before end_time
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/82a456bc0b7a8e12.
Report an issue: GitHub.