vitest-dev/vitest · error · Error

"@opentelemetry/api" is not installed locally. Make sure you

Error message

"@opentelemetry/api" is not installed locally. Make sure you have setup OpenTelemetry instrumentation: https://vitest.dev/guide/open-telemetry

What it means

The Traces constructor (traces.ts:54-66) dynamically imports @opentelemetry/api when tracing is enabled; if that import rejects (package not installed), it throws this error pointing to the OpenTelemetry setup guide. OpenTelemetry tracing is opt-in and requires the user to install the API package and an SDK.

Source

Thrown at packages/vitest/src/utils/traces.ts:65

  #noopContext = createNoopContext()
  #initStartTime = performance.now()
  #initEndTime = 0
  #initRecorded = false

  constructor(options: TracesOptions) {
    if (options.enabled) {
      const apiInit = import('@opentelemetry/api').then((api) => {
        const otel = {
          tracer: api.trace.getTracer(options.tracerName || 'vitest'),
          context: api.context,
          propagation: api.propagation,
          trace: api.trace,
          SpanKind: api.SpanKind,
          SpanStatusCode: api.SpanStatusCode,
        }
        this.#otel = otel
      }).catch(() => {
        throw new Error(`"@opentelemetry/api" is not installed locally. Make sure you have setup OpenTelemetry instrumentation: https://vitest.dev/guide/open-telemetry`)
      })
      const sdkInit = (options.sdkPath ? import(/* @vite-ignore */ options.sdkPath!) : Promise.resolve()).catch((cause) => {
        throw new Error(`Failed to import custom OpenTelemetry SDK script (${options.sdkPath}): ${cause.message}`)
      })
      this.#init = Promise.all([sdkInit, apiInit]).then(([sdk]) => {
        if (sdk != null) {
          if (sdk.default != null && typeof sdk.default === 'object' && typeof sdk.default.shutdown === 'function') {
            this.#sdk = sdk.default
          }
          else if (options.watchMode !== true && process.env.VITEST_MODE !== 'watch') {
            console.warn(`OpenTelemetry instrumentation module (${options.sdkPath}) does not have a default export with a "shutdown" method. Vitest won't be able to ensure that all traces are processed in time. Try running Vitest in watch mode instead.`)
          }
        }
      }).finally(() => {
        this.#initEndTime = performance.now()
        this.#init = null
      })
    }

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Install @opentelemetry/api: `pnpm add @opentelemetry/api` (and your chosen OTel SDK + exporter).
  2. Follow https://vitest.dev/guide/open-telemetry to wire the SDK and exporter.
  3. If you did not mean to enable tracing, remove the --tracing flag / set traces.enabled: false.

Example fix

# before: tracing enabled without the dependency
vitest run --tracing

# after: install then run
pnpm add @opentelemetry/api
vitest run --tracing
Defensive patterns

Strategy: validation

Validate before calling

import { isBuiltin } from 'node:module'

async function assertOpenTelemetryInstalled() {
  try {
    await import('@opentelemetry/api')
  } catch {
    throw new Error(
      '@opentelemetry/api is not installed. Run `npm i @opentelemetry/api` before enabling tracing.'
    )
  }
}

Prevention

When it happens

Trigger: Enabling tracing (e.g. via the --tracing flag or programmatic config with traces.enabled: true) in a project where @opentelemetry/api is not installed as a dependency. The dynamic import at line 54 rejects and the .catch rethrows this error during Traces construction/waitInit.

Common situations: Following the OpenTelemetry guide but forgetting `npm i @opentelemetry/api`; enabling tracing in CI without adding the dependency; the package being hoisted away in a monorepo so the worker cannot resolve it.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/2981a1e4288fd27d.json. Report an issue: GitHub.