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

  1. Use the static factory: TracerProvider.getTracer(name, version) (or trace.getTracer from @opentelemetry/api, which routes there)
  2. If you need a custom/full SDK provider, register your own provider via the official @opentelemetry/api trace.setTracerProvider instead of instantiating Deno's
  3. 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

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


AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20). Data as JSON: /api/errors/4b409369ea8a71d1. Report an issue: GitHub.