From 7e73320e5365e7b0f63532c42b4bba1e950f332c Mon Sep 17 00:00:00 2001 From: A Tobey Date: Mon, 9 Feb 2026 00:49:59 +0000 Subject: [PATCH] fix(span): skip zero parent span id from empty traceparent (#23) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When --tp-ignore-env is set, LoadTraceparent returns a traceparent with Initialized=true but zeroed SpanId. The code unconditionally copied this into ParentSpanId, producing a span with an all-zeros parent that looks like it has a parent when it doesn't. Now checks bytes.Equal against GetEmptySpanId() before setting parent. Fixes #23 🤖 Claude --- data_for_test.go | 26 ++++++++++++++++++++++++++ otelcli/config_span.go | 6 +++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/data_for_test.go b/data_for_test.go index 11bf2bc..ba41e2c 100644 --- a/data_for_test.go +++ b/data_for_test.go @@ -1243,6 +1243,32 @@ var suites = []FixtureSuite{ }, }, }, + // #23: --tp-ignore-env should not produce a zero-valued parent span id + { + { + Name: "#23 --tp-ignore-env should not send zero parent span id", + Config: FixtureConfig{ + CliArgs: []string{ + "span", + "--endpoint", "{{endpoint}}", + "--tp-ignore-env", + "--name", "test-tp-ignore", + }, + Env: map[string]string{ + "TRACEPARENT": "00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-01", + }, + }, + Expect: Results{ + Config: otelcli.DefaultConfig(), + SpanData: map[string]string{ + "trace_id": "*", + "span_id": "*", + "parent_span_id": "", + }, + SpanCount: 1, + }, + }, + }, // full-system test --otlp-headers makes it to grpc/http servers { { diff --git a/otelcli/config_span.go b/otelcli/config_span.go index a5cf0e8..b2d9202 100644 --- a/otelcli/config_span.go +++ b/otelcli/config_span.go @@ -1,6 +1,7 @@ package otelcli import ( + "bytes" "encoding/hex" "fmt" "io" @@ -42,7 +43,10 @@ func (c Config) NewProtobufSpan() *tracepb.Span { tp := c.LoadTraceparent() if tp.Initialized { span.TraceId = tp.TraceId - span.ParentSpanId = tp.SpanId + // only set parent span id when the traceparent has a real (non-zero) span id (#23) + if !bytes.Equal(tp.SpanId, otlpclient.GetEmptySpanId()) { + span.ParentSpanId = tp.SpanId + } } } else { span.TraceId = otlpclient.GetEmptyTraceId()