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 attributes

View on GitHub (pinned to 806f444784)

Solutions

  1. Set the trace_id argument on the get_trace_topology call to a non-empty trace ID.
  2. If the ID comes from a prior tool call or pipeline step, check that step actually produced it before calling this tool.
  3. 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

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


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/82a456bc0b7a8e12. Report an issue: GitHub.