{"record":{"id":"821d693d5b9d11d4","repo":"pinpoint-apm/pinpoint","slug":"spaneventlist-is-empty","errorCode":null,"errorMessage":"spanEventList is empty.","messagePattern":"spanEventList is empty\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/GrpcSpanProcessorV2.java","lineNumber":128,"sourceCode":"                pSpanEvent.setDepth(depth);\n            } else {\n                int currentDepth = spanEvent.getDepth();\n\n                if (currentDepth == prevDepth) {\n                    // skip\n                    pSpanEvent.setDepth(0);\n                } else {\n                    pSpanEvent.setDepth(currentDepth);\n                }\n                prevDepth = currentDepth;\n            }\n        }\n    }\n\n\n    private long getKeyTime(List<SpanEvent> spanEventList) {\n        if (CollectionUtils.isEmpty(spanEventList)) {\n            throw new IllegalArgumentException(\"spanEventList is empty.\");\n        }\n        final SpanEvent first = spanEventList.get(0);\n        if (first == null) {\n            throw new IllegalStateException(\"first SpanEvent is null\");\n        }\n\n        return first.getStartTime();\n    }\n\n}\n","sourceCodeStart":110,"sourceCodeEnd":139,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/GrpcSpanProcessorV2.java#L110-L139","documentation":"GrpcSpanProcessorV2.getKeyTime derives the key timestamp for a span's event list by taking the start time of the first SpanEvent. Before doing so it asserts the list is non-empty; if it is empty, it throws IllegalArgumentException because there is no event to derive a timestamp from. This is an internal invariant: the profiler's span compression pipeline expects at least one SpanEvent when computing the key time.","triggerScenarios":"Calling keyTime() (via GrpcSpanProcessorV2 span processing during gRPC span serialization) with a List<SpanEvent> that has zero elements — e.g. a Span with no span events recorded before the span is flushed to the collector.","commonSituations":"Spans completed without any child events (async spans, filtered-out events, or tracing plugins that produce empty event lists); custom interceptors that remove or never add SpanEvents; races where events are cleared before the span is sent.","solutions":["Check why the Span reaching GrpcSpanProcessorV2 has an empty spanEventList; ensure at least one SpanEvent is added before the span is completed/flushed.","Guard in calling code: if span.getSpanEventList() is empty, skip key-time computation or use the span's own start time.","Upgrade Pinpoint agent — newer versions tolerate empty event lists in the compression pipeline.","If a custom plugin/filter strips SpanEvents, fix the plugin to preserve at least the root event."],"exampleFix":"// before\nlong keyTime = grpcSpanProcessor.keyTime(span.getSpanEventList());\n\n// after\nList<SpanEvent> events = span.getSpanEventList();\nlong keyTime = (events != null && !events.isEmpty())\n        ? events.get(0).getStartTime()\n        : span.getStartTime();","handlingStrategy":"validation","validationCode":"if (spanEventList == null || spanEventList.isEmpty()) {\n    // skip key-time computation or fall back to span start time\n    return span.getStartTime();\n}","typeGuard":null,"tryCatchPattern":"try {\n    long keyTime = processor.keyTime(span.getSpanEventList());\n} catch (IllegalArgumentException e) {\n    logger.warn(\"Span {} has empty event list; using span start time\", span.getSpanId(), e);\n    keyTime = span.getStartTime();\n}","preventionTips":["Never complete/flush a span before at least one SpanEvent is recorded, or accept spans with empty event lists downstream.","Audit custom plugins/interceptors that might remove all SpanEvents.","Add a pre-serialization assertion that event lists are non-empty in trace tests."],"tags":["java","empty-list","internal-invariant","grpc","tracing"],"backgroundTag":"empty-required-field","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}