{"record":{"id":"b1c59a589991660a","repo":"jaegertracing/jaeger","slug":"span-ids-exceeds-maximum-limit-requested-d-max","errorCode":null,"errorMessage":"span_ids exceeds maximum limit: requested %d, max allowed %d","messagePattern":"span_ids exceeds maximum limit: requested (.+?), max allowed (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_span_details.go","lineNumber":136,"sourceCode":"\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)\n\t}\n\n\t// Validate every span_id up front so a malformed value fails fast instead of\n\t// triggering a backend query that can never match a real span ID. Collect the\n\t// canonical lowercase hex form so the lookup set agrees with the ID the trace\n\t// iterator emits regardless of the request's casing.\n\tcanonicalSpanIDs := make([]string, 0, len(input.SpanIDs))\n\tfor _, spanIDStr := range input.SpanIDs {\n\t\tspanID, err := parseSpanID(spanIDStr)","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_span_details.go#L118-L154","documentation":"The get_span_details handler enforces a configured cap (h.maxSpanDetailsPerRequest) on how many span_ids may be requested at once. buildQuery rejects requests exceeding it with this formatted message, which includes both the requested and allowed counts, before any backend query is made.","triggerScenarios":"Calling the get_span_details MCP tool with input.SpanIDs containing more entries than maxSpanDetailsPerRequest, e.g. 200 span IDs when the limit is 100.","commonSituations":"Batch scripts expanding a large trace's full span list into one request; agents copying every span ID found in an earlier response instead of a focused subset; a lowered server-side limit after a config change.","solutions":["Reduce span_ids to the configured maximum (the error states both numbers).","Chunk the lookup into multiple requests, each within the limit.","Request only the specific spans of interest rather than all spans.","If the default limit is genuinely too low for your workflow, raise maxSpanDetailsPerRequest in the jaeger-query MCP extension configuration."],"exampleFix":"// before\nSpanIDs: allSpans // 250 ids, limit 100\n// after\nSpanIDs: allSpans[:100] // chunk 1 of 3; send remaining ids in follow-up requests","handlingStrategy":"validation","validationCode":"const maxSpanDetailsPerRequest = 100 // must match h.maxSpanDetailsPerRequest\nfunc withinSpanLimit(spanIDs []string) bool {\n\treturn len(spanIDs) <= maxSpanDetailsPerRequest\n}","typeGuard":null,"tryCatchPattern":"out, _, err := handler.Handle(ctx, req, input)\nif err != nil && strings.Contains(err.Error(), \"span_ids exceeds maximum limit\") {\n\tfor chunk := range slices.Chunk(input.SpanIDs, maxSpanDetailsPerRequest) {\n\t\tinput.SpanIDs = chunk\n\t\tout, _, err = handler.Handle(ctx, req, input)\n\t}\n}","preventionTips":["Chunk span ID lists to the configured limit before calling.","Request only the spans you actually need.","Read the limit value from the error message rather than assuming it.","If you routinely hit the cap, raise maxSpanDetailsPerRequest server-side deliberately."],"tags":["mcp","validation","rate-limit","jaeger"],"backgroundTag":"request-limit-exceeded","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}