{"record":{"id":"c7e33b3acf8bec5b","repo":"openclaw/openclaw","slug":"refusing-to-overwrite-foreign-chrome-extension-dir","errorCode":null,"errorMessage":"Refusing to overwrite foreign Chrome extension directory: ${target}","messagePattern":"Refusing to overwrite foreign Chrome extension directory: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/browser/src/browser/extension-install-layout.ts","lineNumber":269,"sourceCode":"        await fs.chmod(targetPath, 0o600);\n      }\n    }\n  }\n}\n\n/** Copy/update the bundled extension with rollback-safe same-directory renames. */\nexport async function installStableChromeExtension(\n  bundledDir: string,\n  deps: ExtensionInstallDeps = {},\n): Promise<string> {\n  const source = await fs.realpath(path.resolve(bundledDir));\n  await assertOwnedPath(source, \"directory\", { allowRootOwner: true });\n  const target = stableChromeExtensionDir(deps);\n  await ensurePrivateDirectory(path.resolve(deps.stateDir ?? resolveStateDir(deps.env)));\n  await ensurePrivateDirectory(path.dirname(target));\n  const existing = await inspectInstalledCopy(target);\n  if (existing.present && !existing.owned) {\n    throw new Error(`Refusing to overwrite foreign Chrome extension directory: ${target}`);\n  }\n  const suffix = `${process.pid}-${crypto.randomBytes(6).toString(\"hex\")}`;\n  const temporary = `${target}.tmp-${suffix}`;\n  const previous = `${target}.previous-${suffix}`;\n  try {\n    await copyRuntimeTree(source, temporary);\n    await fs.writeFile(\n      path.join(temporary, OWNED_COPY_MARKER),\n      `${JSON.stringify({ v: 1, owner: \"openclaw\" })}\\n`,\n      { mode: 0o600, flag: \"wx\" },\n    );\n    if (existing.present) {\n      await fs.rename(target, previous);\n    }\n    try {\n      await fs.rename(temporary, target);\n    } catch (error) {\n      if (existing.present) {","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/openclaw/openclaw/blob/01804a75319da4b69c9ab98ceaa30477e22b8c0b/extensions/browser/src/browser/extension-install-layout.ts#L251-L287","documentation":"Thrown by installStableChromeExtension when an existing target directory is present but is not marked as owned by OpenClaw (no valid OWNED_COPY_MARKER with v:1). The installer will not overwrite a Chrome extension directory it did not create, to avoid clobbering a user's manually-installed extension or one owned by another tool.","triggerScenarios":"A previous manual install of the Chrome extension in the same target; a leftover directory from an older OpenClaw version that predated the ownership marker; a foreign tool that writes to the same path; a marker file that got corrupted or removed.","commonSituations":"Switching from a manual install to the managed installer; downgrading OpenClaw past the marker version; another Chrome extension manager claiming the same directory; partial cleanup that removed the marker.","solutions":["Inspect the target directory; if it is safe to remove, delete it and rerun the installer.","If the directory should be owned by OpenClaw, recreate the OWNED_COPY_MARKER with {\"v\":1,\"owner\":\"openclaw\"}.","Point the state dir elsewhere to install into a fresh location."],"exampleFix":"// before\n$ openclaw browser extension install  # target dir exists, not owned\n// after\n$ rm -rf ~/.openclaw/browser/chrome-extension && openclaw browser extension install","handlingStrategy":"try-catch","validationCode":"const existing = await inspectInstalledCopy(target);\nif (existing.present && !existing.owned) {\n  throw new Error('target has foreign extension dir; remove it first');\n}","typeGuard":null,"tryCatchPattern":"try { await installStableChromeExtension(bundledDir); }\ncatch (err) {\n  if (/foreign Chrome extension directory/.test(String(err))) {\n    await fs.rm(target, { recursive: true, force: true });\n    await installStableChromeExtension(bundledDir);\n  } else throw err;\n}","preventionTips":["Let OpenClaw own the extension directory exclusively.","Remove foreign extension dirs before first install.","Do not share the extension directory with other tools."],"tags":["filesystem","security","ownership","install","bundled-extension"],"backgroundTag":null,"analyzedSha":"01804a75319da4b69c9ab98ceaa30477e22b8c0b","analyzedAt":"2026-08-12T04:37:58.197Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}