In packages/logfire-node/src/logfireConfig.ts, resolveDistributedTracing (around line 452) evaluates (option ?? envValue === undefined) ? true : envValue === 'true'. When the option is false, the nullish coalescing keeps false and the ternary falls through to the env branch, so the environment variable silently wins over explicit code:
process.env.LOGFIRE_DISTRIBUTED_TRACING = 'true'
logfire.configure({ distributedTracing: false })
// logfireConfig.distributedTracing === true
Meanwhile distributedTracing: true with LOGFIRE_DISTRIBUTED_TRACING=false correctly resolves to true, so the precedence is asymmetric: code wins one way but not the other. Every other configure() setting lets the code option win over its env var, and the docs describe distributedTracing: false as the way to suppress incoming trace context extraction. Reproduced on current main. Related smaller quirk: an empty LOGFIRE_DISTRIBUTED_TRACING value (set but blank) currently disables distributed tracing instead of being treated as unset, unlike the readNonEmptyEnv convention used for the other env vars.
I took a stab at a fix on my fork: https://github.com/ayaangazali/logfire-js/tree/distributed-tracing-precedence (built with Claude Code's help, went through the diff myself). Code option wins unconditionally, non-empty env is parsed as before when the option is omitted, empty env counts as unset, plus six regression tests in logfireConfig.test.ts and a patch changeset. pnpm run check is green. happy to open the PR if the approach looks right, or no worries if you'd rather fold it into something else. still learning my way around the config layer, so poke holes if I misread the intent :)
In
packages/logfire-node/src/logfireConfig.ts,resolveDistributedTracing(around line 452) evaluates(option ?? envValue === undefined) ? true : envValue === 'true'. When the option isfalse, the nullish coalescing keepsfalseand the ternary falls through to the env branch, so the environment variable silently wins over explicit code:Meanwhile
distributedTracing: truewithLOGFIRE_DISTRIBUTED_TRACING=falsecorrectly resolves totrue, so the precedence is asymmetric: code wins one way but not the other. Every other configure() setting lets the code option win over its env var, and the docs describedistributedTracing: falseas the way to suppress incoming trace context extraction. Reproduced on current main. Related smaller quirk: an emptyLOGFIRE_DISTRIBUTED_TRACINGvalue (set but blank) currently disables distributed tracing instead of being treated as unset, unlike thereadNonEmptyEnvconvention used for the other env vars.I took a stab at a fix on my fork: https://github.com/ayaangazali/logfire-js/tree/distributed-tracing-precedence (built with Claude Code's help, went through the diff myself). Code option wins unconditionally, non-empty env is parsed as before when the option is omitted, empty env counts as unset, plus six regression tests in logfireConfig.test.ts and a patch changeset.
pnpm run checkis green. happy to open the PR if the approach looks right, or no worries if you'd rather fold it into something else. still learning my way around the config layer, so poke holes if I misread the intent :)