denoland/deno · error · TypeError
TracerProvider can not be constructed
Error message
TracerProvider can not be constructed
What it means
Deno's built-in OpenTelemetry implementation registers TracerProvider on the OpenTelemetry JS API global (globalThis[Symbol.for("opentelemetry.js.api.1")].trace) when tracing is enabled. The class is a namespace of statics with a private-constructor guard: new TracerProvider() always throws. Tracers are obtained via the static factory TracerProvider.getTracer(name, version?, options?).
Source
Thrown at ext/telemetry/telemetry.ts:341
op_otel_span_attribute1(
span,
attributesLocation,
attributesTarget,
attributeKvs[i][0],
attributeKvs[i][1],
);
i += 1;
}
}
}
interface TracerOptions {
schemaUrl?: string;
}
class TracerProvider {
constructor() {
throw new TypeError("TracerProvider can not be constructed");
}
static getTracer(
name: string,
version?: string,
options?: TracerOptions,
): Tracer {
const tracer = new OtelTracer(name, version, options?.schemaUrl);
return new Tracer(tracer);
}
}
class Tracer {
#tracer: OtelTracer;
constructor(tracer: OtelTracer) {
this.#tracer = tracer;
}View on GitHub (pinned to a961cdec3b)
Solutions
- Use the static factory: TracerProvider.getTracer(name, version) (or trace.getTracer from @opentelemetry/api, which routes there)
- If you need a custom/full SDK provider, register your own provider via the official @opentelemetry/api trace.setTracerProvider instead of instantiating Deno's
- Check the API surface before use: typeof TracerProvider.getTracer === "function" to confirm you have Deno's built-in provider
Example fix
// before
const otel = globalThis[Symbol.for("opentelemetry.js.api.1")];
const provider = new otel.trace("my-app"); // TypeError: can not be constructed
// after
const tracer = otel.trace.getTracer("my-app", "1.0.0"); Defensive patterns
Strategy: validation
Validate before calling
const otel = globalThis[Symbol.for("opentelemetry.js.api.1")];
if (otel?.trace && typeof otel.trace.getTracer === "function") {
const tracer = otel.trace.getTracer("app", "1.0.0"); // never `new otel.trace`
} Type guard
const isDenoOtelProvider = (provider: unknown): provider is { getTracer(name: string, version?: string): unknown } =>
typeof (provider as { getTracer?: unknown })?.getTracer === "function"; Try / catch
try { provider = new ProviderClass(name); } catch (err) { if (err instanceof TypeError && err.message.includes("can not be constructed")) { tracer = ProviderClass.getTracer(name); } else throw err; } Prevention
- Never instantiate provider classes from OTel API globals; always use getTracer/getMeter factories
- Pin @opentelemetry/api versions compatible with Deno's built-in shim
- For custom SDK providers, register them via trace.setTracerProvider instead of replacing Deno's global
When it happens
Trigger: Executing new TracerProvider() against the Deno-provided provider — e.g. new otel.trace() on the global symbol, or an @opentelemetry/api-compatible library that instantiates the provider class it found on the global instead of calling getTracer; most common when running with Deno's built-in OTel enabled (OTEL_DENO / OTEL_EXPORTER_OTLP_* configured).
Common situations: Swapping @opentelemetry/api's real TraceApi for Deno's shim and assuming it's instantiable; code written for the SDK's NodeTracerProvider being pointed at Deno's built-in provider; version drift between OTel API packages and Deno's compat shim.
Related errors
- startActiveSpan requires a function argument
- Failed to inject with ${propagator.constructor.name}.
- Failed to extract with ${propagator.constructor.name}.
- ERR_ILLEGAL_CONSTRUCTOR
- Illegal constructor
AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20).
Data as JSON: /api/errors/4b409369ea8a71d1.
Report an issue: GitHub.