{"record":{"id":"3e96dc18ae5edce4","repo":"jaegertracing/jaeger","slug":"trace-id-is-required-3e96dc","errorCode":null,"errorMessage":"trace_id is required","messagePattern":"trace_id is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_span_details.go","lineNumber":127,"sourceCode":"\n\t// Report any span IDs that were not found\n\tif len(spanIDSet) > 0 {\n\t\tmissingIDs := make([]string, 0, len(spanIDSet))\n\t\tfor spanID := range spanIDSet {\n\t\t\tmissingIDs = append(missingIDs, spanID)\n\t\t}\n\t\toutput.Error = fmt.Sprintf(\"spans not found: %v\", missingIDs)\n\t}\n\n\treturn nil, output, nil\n}\n\n// buildQuery converts GetSpanDetailsInput to querysvc.GetTraceParams and returns\n// the requested span IDs in canonical lowercase hex form for the lookup set.\nfunc (h *getSpanDetailsHandler) buildQuery(input types.GetSpanDetailsInput) (querysvc.GetTraceParams, []string, error) {\n\t// Validate input\n\tif input.TraceID == \"\" {\n\t\treturn querysvc.GetTraceParams{}, nil, errors.New(\"trace_id is required\")\n\t}\n\n\tif len(input.SpanIDs) == 0 {\n\t\treturn querysvc.GetTraceParams{}, nil, errors.New(\"span_ids is required and must not be empty\")\n\t}\n\n\t// Validate span count against configured limit\n\tif len(input.SpanIDs) > h.maxSpanDetailsPerRequest {\n\t\treturn querysvc.GetTraceParams{}, nil, fmt.Errorf(\n\t\t\t\"span_ids exceeds maximum limit: requested %d, max allowed %d\",\n\t\t\tlen(input.SpanIDs),\n\t\t\th.maxSpanDetailsPerRequest,\n\t\t)\n\t}\n\n\ttraceID, err := parseTraceID(input.TraceID)\n\tif err != nil {\n\t\treturn querysvc.GetTraceParams{}, nil, fmt.Errorf(\"invalid trace_id: %w\", err)","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_span_details.go#L109-L145","documentation":"The buildQuery helper of get_span_details validates that a trace ID was supplied before building querysvc.GetTraceParams. An empty TraceID cannot be parsed into a pcommon.TraceID, so the handler returns this sentinel error immediately.","triggerScenarios":"Calling the get_span_details MCP tool with TraceID == \"\" while span_ids are provided; typically a client omitted the trace_id argument entirely.","commonSituations":"MCP tool schema lacking required-field enforcement; an orchestration step forwarding empty context; UI form submitted without selecting a trace.","solutions":["Supply a non-empty trace_id alongside span_ids","Add required-field validation in the MCP client or tool input schema","Guard chained tool calls so a failed upstream lookup does not propagate an empty ID"],"exampleFix":"// before\nreq := types.GetSpanDetailsInput{SpanIDs: spanIDs}\n// after\nif traceID == \"\" {\n    return errors.New(\"cannot call get_span_details without trace_id\")\n}\nreq := types.GetSpanDetailsInput{TraceID: traceID, SpanIDs: spanIDs}","handlingStrategy":"validation","validationCode":"if input.TraceID == \"\" {\n    return errors.New(\"refusing to call get_span_details without trace_id\")\n}","typeGuard":null,"tryCatchPattern":"out, err := handler.Handle(ctx, req, input)\nif err != nil && strings.Contains(err.Error(), \"trace_id is required\") {\n    return fmt.Errorf(\"get_span_details requires trace_id; got empty input\")\n}","preventionTips":["Make trace_id a required field in the tool schema","Propagate trace IDs through explicit, checked variables rather than nullable context","Fail fast upstream when a trace lookup returns nothing instead of passing \"\" onward"],"tags":["jaeger","mcp","validation","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}