{"record":{"id":"28d06a2c52dc0c40","repo":"jaegertracing/jaeger","slug":"trace-id-is-required","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_critical_path.go","lineNumber":94,"sourceCode":"\t}\n\n\t// Compute critical path\n\tcriticalPathSections, err := criticalpath.ComputeCriticalPathFromTraces(trace)\n\tif err != nil {\n\t\treturn nil, types.GetCriticalPathOutput{}, fmt.Errorf(\"failed to compute critical path: %w\", err)\n\t}\n\n\t// Build output\n\toutput := h.buildOutput(input.TraceID, trace, criticalPathSections)\n\n\treturn nil, output, nil\n}\n\n// buildQuery converts GetCriticalPathInput to querysvc.GetTraceParams.\nfunc (*getCriticalPathHandler) buildQuery(input types.GetCriticalPathInput) (querysvc.GetTraceParams, error) {\n\t// Validate input\n\tif input.TraceID == \"\" {\n\t\treturn querysvc.GetTraceParams{}, errors.New(\"trace_id is required\")\n\t}\n\n\ttraceID, err := parseTraceID(input.TraceID)\n\tif err != nil {\n\t\treturn querysvc.GetTraceParams{}, fmt.Errorf(\"invalid trace_id: %w\", err)\n\t}\n\n\treturn querysvc.GetTraceParams{\n\t\tTraceIDs: []tracestore.GetTraceParams{\n\t\t\t{TraceID: traceID},\n\t\t},\n\t\tRawTraces: false, // We want adjusted traces\n\t}, nil\n}\n\n// buildOutput constructs the GetCriticalPathOutput from the trace and critical path sections.\nfunc (*getCriticalPathHandler) buildOutput(\n\ttraceIDStr string,","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_critical_path.go#L76-L112","documentation":"The buildQuery helper of the get_critical_path MCP handler validates input before converting GetCriticalPathInput to querysvc.GetTraceParams. When input.TraceID is the empty string it cannot form a trace lookup, so it fails fast with this sentinel error instead of issuing a doomed query.","triggerScenarios":"Invoking the get_critical_path MCP tool with TraceID omitted or set to \"\" — e.g. an LLM client filling the tool arguments without the required trace_id field.","commonSituations":"MCP client schema not enforcing required fields; prompt-generated arguments missing the field; empty variable interpolated into the tool input from an upstream step that produced no trace.","solutions":["Always populate trace_id in the tool input before calling get_critical_path","Enforce required-argument validation in the MCP client/tool schema so the call is rejected before reaching the handler","If the trace ID comes from a prior tool step, check it is non-empty before chaining"],"exampleFix":"// before\ninput := types.GetCriticalPathInput{TraceID: traceIDFromStep} // may be \"\"\n// after\nif traceIDFromStep == \"\" {\n    return fmt.Errorf(\"no trace ID available from previous step\")\n}\ninput := types.GetCriticalPathInput{TraceID: traceIDFromStep}","handlingStrategy":"validation","validationCode":"if input.TraceID == \"\" {\n    return errors.New(\"trace_id is required before calling get_critical_path\")\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(\"caller bug: get_critical_path invoked without trace_id\")\n}","preventionTips":["Mark trace_id as required in the MCP tool input schema","Validate tool arguments at the orchestration layer before dispatch","Avoid chaining tool calls on values that may be empty"],"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"}