{"record":{"id":"33af96980115746b","repo":"decolua/9router","slug":"failed-to-uninstall-certificate-e-message","errorCode":null,"errorMessage":"Failed to uninstall certificate: ${e.message}","messagePattern":"Failed to uninstall certificate: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mitm/cert/install.js","lineNumber":172,"sourceCode":"async function uninstallCertMac(sudoPassword, certPath) {\n  const fingerprint = getCertFingerprint(certPath).replace(/:/g, \"\");\n  const command = `security delete-certificate -Z \"${fingerprint}\" /Library/Keychains/System.keychain`;\n  try {\n    await execWithPassword(command, sudoPassword);\n    log(\"🔐 Cert: ✅ uninstalled from system keychain\");\n  } catch (err) {\n    throw new Error(\"Failed to uninstall certificate\");\n  }\n}\n\nasync function uninstallCertWindows() {\n  // Auto-elevate via UAC popup if not admin\n  const script = `certutil -delstore Root ${quotePs(ROOT_CA_CN)}`;\n  try {\n    await runElevatedPowerShell(script);\n    log(\"🔐 Cert: ✅ uninstalled from Windows Root store\");\n  } catch (e) {\n    throw new Error(`Failed to uninstall certificate: ${e.message}`);\n  }\n}\n\nfunction checkCertInstalledLinux() {\n  const config = getLinuxCertConfig();\n  const certFile = `${config.dir}/9router-root-ca.crt`;\n  return Promise.resolve(fs.existsSync(certFile));\n}\n\nasync function updateNssDatabases(certPath, action = 'add') {\n  const certName = \"9Router MITM Root CA\";\n  \n  const script = `\n    if ! command -v certutil &> /dev/null; then\n      exit 0\n    fi\n    \n    DIRS=\"$HOME/.pki/nssdb $HOME/snap/chromium/current/.pki/nssdb\"","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/mitm/cert/install.js#L154-L190","documentation":"uninstallCertWindows() runs `certutil -delstore Root <CN>` via an auto-elevating PowerShell (UAC). Any failure from the elevated run is rethrown as `Failed to uninstall certificate: <detail>`. It wraps UAC denial, non-admin context, and certutil non-zero exits.","triggerScenarios":"uninstallCert() on Windows when: user declines UAC, elevation fails in non-interactive sessions, certutil -delstore exits non-zero, or the CN quoting (quotePs of ROOT_CA_CN) does not match the installed cert.","commonSituations":"Headless/CI Windows where UAC prompts cannot be shown; cert already deleted by hand so delstore errors; ROOT_CA_CN changed in a version update so the old CN no longer matches; AV blocking certutil.","solutions":["Accept the UAC prompt or run once as Administrator","Verify the cert exists: `certutil -store Root <CN>` in an admin shell","Manually run `certutil -delstore Root <CN>` to see the raw error","If ROOT_CA_CN was renamed, uninstall using the original CN"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const installed = await checkCertInstalled(certPath);\nif (!installed) return; // nothing to remove\n// warn if not elevated\nconst isAdmin = (await exec('net session').catch(() => null)) !== null;\nif (!isAdmin) console.warn('UAC prompt required for cert uninstall');","typeGuard":null,"tryCatchPattern":"try {\n  await uninstallCert(sudoPassword, certPath);\n} catch (e) {\n  if (e.message.startsWith('Failed to uninstall certificate:')) {\n    console.error('certutil delstore failed:', e.message);\n    // fallback: manual `certutil -delstore Root <CN>` as admin\n  } else throw e;\n}","preventionTips":["Verify installed state first so uninstall is a no-op when absent","Warn about UAC before triggering elevation","If ROOT_CA_CN changes between versions, uninstall with the old CN first"],"tags":["windows","certificate","uac","uninstall"],"backgroundTag":"certificate-uninstall-failed","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}