{"record":{"id":"2981a1e4288fd27d","repo":"vitest-dev/vitest","slug":"opentelemetry-api-is-not-installed-locally-mak","errorCode":null,"errorMessage":"\"@opentelemetry/api\" is not installed locally. Make sure you have setup OpenTelemetry instrumentation: https://vitest.dev/guide/open-telemetry","messagePattern":"\"@opentelemetry/api\" is not installed locally\\. Make sure you have setup OpenTelemetry instrumentation: https://vitest\\.dev/guide/open-telemetry","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/utils/traces.ts","lineNumber":65,"sourceCode":"  #noopContext = createNoopContext()\n  #initStartTime = performance.now()\n  #initEndTime = 0\n  #initRecorded = false\n\n  constructor(options: TracesOptions) {\n    if (options.enabled) {\n      const apiInit = import('@opentelemetry/api').then((api) => {\n        const otel = {\n          tracer: api.trace.getTracer(options.tracerName || 'vitest'),\n          context: api.context,\n          propagation: api.propagation,\n          trace: api.trace,\n          SpanKind: api.SpanKind,\n          SpanStatusCode: api.SpanStatusCode,\n        }\n        this.#otel = otel\n      }).catch(() => {\n        throw new Error(`\"@opentelemetry/api\" is not installed locally. Make sure you have setup OpenTelemetry instrumentation: https://vitest.dev/guide/open-telemetry`)\n      })\n      const sdkInit = (options.sdkPath ? import(/* @vite-ignore */ options.sdkPath!) : Promise.resolve()).catch((cause) => {\n        throw new Error(`Failed to import custom OpenTelemetry SDK script (${options.sdkPath}): ${cause.message}`)\n      })\n      this.#init = Promise.all([sdkInit, apiInit]).then(([sdk]) => {\n        if (sdk != null) {\n          if (sdk.default != null && typeof sdk.default === 'object' && typeof sdk.default.shutdown === 'function') {\n            this.#sdk = sdk.default\n          }\n          else if (options.watchMode !== true && process.env.VITEST_MODE !== 'watch') {\n            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.`)\n          }\n        }\n      }).finally(() => {\n        this.#initEndTime = performance.now()\n        this.#init = null\n      })\n    }","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/utils/traces.ts#L47-L83","documentation":"When tracing is enabled, the Traces constructor dynamically imports @opentelemetry/api. Vitest does not bundle OpenTelemetry; it expects the package to be resolvable from the user's project. If the import rejects (module not found), the .catch at traces.ts:64-66 rethrows this error with a link to the setup guide. The rejection is deferred because it lives in a promise chain, so it surfaces when waitInit() is awaited or the init promise settles.","triggerScenarios":"Enabling tracing via the experimentalTraces option (or --experimental-traces CLI flag) while @opentelemetry/api is not resolvable from the Vitest process. The constructor only attempts the import when options.enabled is true.","commonSituations":"Forgot to run npm i @opentelemetry/api; CI install step pruned dev dependencies; pnpm hoisting or monorepo isolation hides the package from the Vitest CWD; upgrading Vitest to a version that introduced tracing without updating the project deps.","solutions":["Install the package: npm i @opentelemetry/api (or the equivalent pnpm/yarn command).","Verify resolution from the same CWD Vitest runs in: node -e \"require.resolve('@opentelemetry/api')\".","Disable tracing (remove --experimental-traces / set experimentalTraces.enabled to false) if you do not need it.","In a monorepo, hoist the dependency or add it to the workspace where Vitest executes."],"exampleFix":"# before\nvitest --experimental-traces   # throws\n\n# after\nnpm i @opentelemetry/api\nvitest --experimental-traces","handlingStrategy":"validation","validationCode":"function canResolveOtelApi() {\n  try {\n    require.resolve('@opentelemetry/api')\n    return true\n  } catch {\n    return false\n  }\n}\nif (config.experimentalTraces?.enabled && !canResolveOtelApi()) {\n  console.warn('Tracing requested but @opentelemetry/api is missing; disabling.')\n  config.experimentalTraces.enabled = false\n}","typeGuard":null,"tryCatchPattern":"try {\n  await traces.waitInit()\n} catch (e) {\n  if (e instanceof Error && /not installed locally/.test(e.message)) {\n    console.warn('OpenTelemetry tracing unavailable:', e.message)\n  } else {\n    throw e\n  }\n}","preventionTips":["Add a pre-flight dependency check in CI before running traced test suites.","Gate the experimentalTraces option behind a canResolveOtelApi() check.","Pin @opentelemetry/api in package.json so an install pruning does not silently drop it.","In monorepos, confirm the package resolves from the exact workspace that runs Vitest."],"tags":["opentelemetry","tracing","dependencies","configuration"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}