CLI crashes when `OTEL_*_EXPORTER=none` is set (standard OpenTelemetry SDK value)
human note: the following was written by claude but iterated on to get the full picture with proof from the obfuscated code. It's a real issue, but it's verbose because claude wrote it
The CLI crashes during startup when any of the OTEL exporter environment variables are set to `none`:
-
OTEL_LOGS_EXPORTER=none -
OTEL_TRACES_EXPORTER=none -
OTEL_METRICS_EXPORTER=none
Stack Trace
Error: Unknown exporter type set in OTEL_LOGS_EXPORTER env var: none
at sf7 (/$bunfs/root/claude:2227:1350)
at EAB (/$bunfs/root/claude:2227:5137)
at e68 (/$bunfs/root/claude:4669:17047)
at WPA (/$bunfs/root/claude:4669:17013)
at JPA (/$bunfs/root/claude:4669:16978)
Expected Behavior
According to the OpenTelemetry SDK Environment Variables specification, none is a valid value for all exporter environment variables:
none: No automatically configured exporter for this signal.
The CLI should recognize none as a valid value and simply skip configuring an exporter for that signal type, rather than throwing an error.
OTEL Spec Compliance Table
| Environment Variable | OTEL Spec Values | CLI Supported Values | Missing Values |
|---|---|---|---|
OTEL_TRACES_EXPORTER |
otlp, zipkin, console, none |
otlp, console |
none, zipkin |
OTEL_METRICS_EXPORTER |
otlp, prometheus, console, none |
otlp, console, prometheus |
none |
OTEL_LOGS_EXPORTER |
otlp, console, none |
otlp, console |
none |
Note: The OTEL spec also defines deprecated values like logging and development values like otlp/stdout, but none is the critical missing value as it's the standard way to disable telemetry.
Why This Matters
Users who have OTEL_*_EXPORTER=none set in their environment (a common way to disable telemetry in OTEL-aware applications) cannot use Claude Code without unsetting those variables first.
This is problematic because:
- Users may have these set globally via shell profiles
- It violates the principle of least surprise - these are standard OTEL values
Reproduction
OTEL_LOGS_EXPORTER=none claude -p "say hi"
Code Location
The issue is in the telemetry initialization code (path /$bunfs/root/claude in the Bun-bundled binary, or cli.js in npm package). Three functions handle the exporter environment variables (minified function names vary by version):
Logs Exporter (gm5 in v0.2.6):
function gm5(){let A=(process.env.OTEL_LOGS_EXPORTER||"").trim().split(",").filter(Boolean),Q=[];for(let B of A)if(B==="console")Q.push(new ds.ConsoleLogRecordExporter);else if(B==="otlp"){/* ... */}else throw Error(`Unknown exporter type set in OTEL_LOGS_EXPORTER env var: ${B}`);return Q}
Traces Exporter (um5 in v0.2.6):
function um5(){let A=(process.env.OTEL_TRACES_EXPORTER||"").trim().split(",").filter(Boolean),Q=[];for(let B of A)if(B==="console")Q.push(new ps.ConsoleSpanExporter);else if(B==="otlp"){/* ... */}else throw Error(`Unknown exporter type set in OTEL_TRACES_EXPORTER env var: ${B}`);return Q}
Metrics Exporter (hm5 in v0.2.6):
function hm5(){let A=(process.env.OTEL_METRICS_EXPORTER||"").trim().split(",").filter(Boolean),/* ... */;for(let G of A)if(G==="console"){/* ... */}else if(G==="otlp"){/* ... */}else if(G==="prometheus")B.push(new sv2.PrometheusExporter);else throw Error(`Unknown exporter type set in OTEL_EXPORTER_OTLP_METRICS_PROTOCOL or OTEL_EXPORTER_OTLP_PROTOCOL env var: ${G}`);/* ... */}
Deobfuscated/reformatted version (logs exporter example)
function getLogExporters() {
let exporterNames = (process.env.OTEL_LOGS_EXPORTER || "").trim().split(",").filter(Boolean);
let exporters = [];
for (let name of exporterNames) {
if (name === "console") {
exporters.push(new ConsoleLogRecordExporter());
} else if (name === "otlp") {
// Configure OTLP exporter based on protocol...
} else {
// BUG: "none" falls through to here and throws
throw Error(`Unknown exporter type set in OTEL_LOGS_EXPORTER env var: ${name}`);
}
}
return exporters;
}
Suggested Fix
Add handling for none in all three exporter configuration functions:
- For each of
OTEL_LOGS_EXPORTER,OTEL_TRACES_EXPORTER, andOTEL_METRICS_EXPORTER:- When iterating through the comma-separated exporter values
- If the value is
"none", skip it (continue to next iteration) - Per OTEL spec:
nonemeans "no automatically configured exporter for this signal"
This is a simple change: add a condition to check for "none" and continue before the existing console/otlp/prometheus checks and before the error throw.
Current Workaround
Unset the environment variables before running Claude:
unset OTEL_LOGS_EXPORTER OTEL_TRACES_EXPORTER OTEL_METRICS_EXPORTER
claude -p "say hi"
Environment
- Claude Code Version: 2.1.7
- OS: macOS
References
🤖 Generated with Claude Code