can1357/oh-my-pi · error · Error
Unable to safely override process.cwd for Puppeteer import
Error message
Unable to safely override process.cwd for Puppeteer import
What it means
Before importing puppeteer-core, importPuppeteerWithSafeCwd temporarily replaces process.cwd with a function returning a safe directory (Puppeteer's cosmiconfig probes cwd during module init). If process.cwd has no own property descriptor whose value is a function — e.g. it was already replaced, deleted, or made non-configurable by other instrumentation — the override is deemed unsafe and this Error is thrown, and the failure is cached (puppeteerCwdFailed) so later imports rethrow it.
Source
Thrown at packages/coding-agent/src/tools/browser/launch.ts:88
}
const STEALTH_ACCEPT_LANGUAGE = "en-US,en";
const USER_AGENT_TARGET_TIMEOUT_MS = 5_000;
const USER_AGENT_TARGET_TYPES = new Set(["page", "webview", "background_page"]);
const PUPPETEER_SOURCE_URL_SUFFIX = "//# sourceURL=__puppeteer_evaluation_script__";
/**
* Lazy-import puppeteer while hiding the user's cwd from cosmiconfig. The
* import must not change the filesystem cwd: it is awaited and callers
* continue running on the main thread while it is pending.
*/
let puppeteerCwdFailed = false;
let puppeteerCwdFailure: unknown;
async function importPuppeteerWithSafeCwd(safeDir: string): Promise<typeof Puppeteer> {
const cwdDescriptor = Object.getOwnPropertyDescriptor(process, "cwd");
if (!cwdDescriptor || typeof cwdDescriptor.value !== "function") {
throw new Error("Unable to safely override process.cwd for Puppeteer import");
}
try {
Object.defineProperty(process, "cwd", { ...cwdDescriptor, value: () => safeDir });
} catch (overrideFailure) {
puppeteerCwdFailed = true;
puppeteerCwdFailure = overrideFailure;
throw overrideFailure;
}
let loaded: typeof Puppeteer | undefined;
let importFailure: unknown;
let importFailed = false;
let restorationFailure: unknown;
let restorationFailed = false;
try {
try {
// Dynamic import is intentional: Puppeteer probes cwd during module initialization.
loaded = (await import("puppeteer-core")).default;View on GitHub (pinned to 9690622007)
Solutions
- Find and remove whatever redefines/deletes process.cwd before browser tooling runs (search for defineProperty(process, "cwd") / process.cwd = in the host code)
- Ensure the original descriptor is restored after any intentional cwd override elsewhere
- Restart the process to clear the cached puppeteerCwdFailed failure after fixing the cause
- As a workaround, launch against an already-running browser (connected CDP kind) that skips the puppeteer import path if available
Example fix
// before: test stub without restoring
process.cwd = () => "/fake"; // or defineProperty with configurable:false
// after: patch and restore with a matching descriptor
const desc = Object.getOwnPropertyDescriptor(process, "cwd")!;
Object.defineProperty(process, "cwd", { ...desc, value: () => "/fake" });
// ...test...
Object.defineProperty(process, "cwd", desc); Defensive patterns
Strategy: try-catch
Validate before calling
const d = Object.getOwnPropertyDescriptor(process, "cwd");
if (!d || typeof d.value !== "function") {
throw new Error("process.cwd is not safely patchable; remove global cwd monkey-patching before using the browser tool");
} Type guard
function cwdIsPatchable(): boolean {
const d = Object.getOwnPropertyDescriptor(process, "cwd");
return !!d && typeof d.value === "function";
} Try / catch
try {
await loadPuppeteer();
} catch (err) {
if (err instanceof Error && err.message.includes("Unable to safely override process.cwd")) {
// find the library that replaced/deleted process.cwd and remove/repair that patch, then restart
}
throw err;
} Prevention
- Never stub/delete process.cwd process-wide (especially with configurable:false); scope cwd changes to chdir-free helpers
- If you must patch cwd, restore the exact original descriptor in a finally block
- Remember the failure is cached for the process lifetime — fix the cause and restart rather than retrying in-process
- Run browser tooling before test frameworks apply global environment patches, or order patches so cwd is untouched
When it happens
Trigger: Another library/test framework monkey-patched or deleted process.cwd (Object.defineProperty(process,'cwd',{...}) or deletion) before the browser tool first imports puppeteer; bundlers/runtimes exposing a non-configurable cwd; a prior import attempt failed to restore cwd (restorationFailed sets puppeteerCwdFailed).
Common situations: Test harnesses that stub process.cwd globally; running under instrumentation that freezes globals; a previous failed puppeteer load poisoning the cached failure for the process lifetime.
Related errors
- Unable to resolve AWS credentials. Configure static environm
- imageUrls exposure "${name}" requires the ${name} binary on
- blob broker worker requires ${BLOB_BROKER_SOCKET_ENV} and ${
- ssh binary not found in PATH
- `omp gallery --screenshot` requires VHS, which is not instal
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/4dcd9d38e03aa47e.
Report an issue: GitHub.