{"record":{"id":"0958e05beb001d1a","repo":"denoland/deno","slug":"benchcontext-end-has-already-been-invoked","errorCode":null,"errorMessage":"BenchContext::end() has already been invoked","messagePattern":"BenchContext::end\\(\\) has already been invoked","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"cli/js/40_bench.js","lineNumber":446,"sourceCode":"          \"The benchmark which this context belongs to is not being executed\",\n        );\n      }\n      if (currentBenchUserExplicitStart != null) {\n        throw new TypeError(\n          \"BenchContext::start() has already been invoked\",\n        );\n      }\n      currentBenchUserExplicitStart = benchNow();\n    },\n    end() {\n      const end = benchNow();\n      if (currentBenchId !== desc.id) {\n        throw new TypeError(\n          \"The benchmark which this context belongs to is not being executed\",\n        );\n      }\n      if (currentBenchUserExplicitEnd != null) {\n        throw new TypeError(\"BenchContext::end() has already been invoked\");\n      }\n      currentBenchUserExplicitEnd = end;\n    },\n  };\n}\n\n/** Wrap a user benchmark function in one which returns a structured result. */\nfunction wrapBenchmark(desc) {\n  const fn = desc.fn;\n  return async function outerWrapped() {\n    let token = null;\n    const originalConsole = globalThis.console;\n    currentBenchId = desc.id;\n\n    try {\n      globalThis.console = new Console((s) => {\n        op_dispatch_bench_event({ output: s });\n      });","sourceCodeStart":428,"sourceCodeEnd":464,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/js/40_bench.js#L428-L464","documentation":"`deno ci` requires a lockfile and then deletes the existing `node_modules` directory for a clean, reproducible install. This wrapper reports the underlying `fs::remove_dir_all` failure with the directory path, keeping the original OS error (`{err}`) in the message. It fails before any dependency is installed, so the environment is left as-is.","triggerScenarios":"`deno ci` when `node_modules` exists and cannot be removed: a file inside is held open by a running process (dev server, editor, esbuild service — classic on Windows), the directory or its contents are owned by another user (previous sudo run), or the filesystem is read-only (container, CI cache mount).","commonSituations":"Windows developers with a running `deno task dev`/editor holding DLLs/JS files; unix users who previously ran `sudo deno install` leaving root-owned files; CI with a read-only or incorrectly permissioned cache volume.","solutions":["Stop processes that hold files in node_modules (dev servers, editors, running tools) and re-run `deno ci`","Fix ownership if a sudo run created root-owned files: `sudo chown -R \"$(id -un):$(id -gn)\" node_modules` then retry","Delete manually if removal is stuck: `rm -rf node_modules` (Windows: close apps first or use `rmdir /s /q node_modules`) then re-run","Avoid running deno with sudo; ensure CI mounts are writable"],"exampleFix":"# before\n$ deno ci\n# failed to remove .../node_modules: Directory not empty (os error 39)\n\n# after\n$ sudo chown -R \"$(id -un)\" node_modules && rm -rf node_modules\n$ deno ci  # clean install succeeds","handlingStrategy":"retry","validationCode":"# Pre-flight: confirm node_modules is removable before deno ci\n[ ! -d node_modules ] || { touch node_modules/.probe && rm node_modules/.probe; } || echo \"node_modules not writable — fix perms first\"","typeGuard":null,"tryCatchPattern":"Wrap `deno ci` with bounded retry on this message: the classic cause (a process holding files) resolves once that process exits — kill dev servers/editors, wait a few seconds, retry once or twice; if the message persists, fall back to `rm -rf node_modules` and a final `deno ci`.","preventionTips":["Stop dev servers and close editors before running `deno ci` (especially on Windows)","Never run deno install/ci with sudo, which leaves root-owned files that later block removal","In CI, ensure the workspace/cache volume is writable by the CI user"],"tags":["node-modules","filesystem","permissions","ci","install"],"backgroundTag":"cannot-delete-directory","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}