Found while implementing #33.
In otelcli/exec.go, the {{traceparent}} argument substitution uses the function-scoped tp variable:
var tp traceparent.Traceparent
if config.GetIsRecording() {
tp = otlpclient.TraceparentFromProtobufSpan(span, ...) // assigned
injectTraceparent(tp, appendChildEnv)
} else if !config.TraceparentIgnoreEnv {
passthrough := config.LoadTraceparent() // outer tp NOT assigned
if passthrough.Initialized {
injectTraceparent(passthrough, appendChildEnv)
}
}
...
tpArgs[i] = strings.Replace(arg, "{{traceparent}}", tp.Encode(), -1) // uses outer tp
In non-recording mode the outer tp is never assigned, so tp.Encode() yields an all-zero traceparent (00-000…0-000…0-00). The child's TRACEPARENT env var is correct (it goes through injectTraceparent(passthrough, …)), but the {{traceparent}} arg substitution is not — they disagree.
Repro
TRACEPARENT=00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-01 \
otel-cli exec -- echo '{{traceparent}}'
# prints 00-000...0-000...0-00 instead of the passed-through traceparent
This predates #33 (the inner variable was previously also named tp, shadowing the outer); #33 renamed it to passthrough for clarity but preserved the behavior.
Fix sketch
Assign the passthrough traceparent to the outer tp in the non-recording branch so arg substitution and env injection use the same value. Add a functional fixture: non-recording exec ... echo {{traceparent}} with a TRACEPARENT in env should echo the passed-through (lower-cased) traceparent.
Found while implementing #33.
In
otelcli/exec.go, the{{traceparent}}argument substitution uses the function-scopedtpvariable:In non-recording mode the outer
tpis never assigned, sotp.Encode()yields an all-zero traceparent (00-000…0-000…0-00). The child'sTRACEPARENTenv var is correct (it goes throughinjectTraceparent(passthrough, …)), but the{{traceparent}}arg substitution is not — they disagree.Repro
This predates #33 (the inner variable was previously also named
tp, shadowing the outer); #33 renamed it topassthroughfor clarity but preserved the behavior.Fix sketch
Assign the passthrough traceparent to the outer
tpin the non-recording branch so arg substitution and env injection use the same value. Add a functional fixture: non-recordingexec ... echo {{traceparent}}with a TRACEPARENT in env should echo the passed-through (lower-cased) traceparent.