{"record":{"id":"ee7282d0fa833e05","repo":"decolua/9router","slug":"certificate-file-not-found-certpath","errorCode":null,"errorMessage":"Certificate file not found: ${certPath}","messagePattern":"Certificate file not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mitm/cert/install.js","lineNumber":88,"sourceCode":"    // Check by SHA1 fingerprint — detects stale cert with same CN but different key\n    let fingerprint;\n    try {\n      fingerprint = getCertFingerprint(certPath).replace(/:/g, \"\");\n    } catch {\n      return resolve(false);\n    }\n    exec(`certutil -store Root ${fingerprint}`, { windowsHide: true }, (error) => {\n      resolve(!error);\n    });\n  });\n}\n\n/**\n * Install SSL certificate to system trust store\n */\nasync function installCert(sudoPassword, certPath) {\n  if (!fs.existsSync(certPath)) {\n    throw new Error(`Certificate file not found: ${certPath}`);\n  }\n\n  const isInstalled = await checkCertInstalled(certPath);\n  if (isInstalled) {\n    log(\"🔐 Cert: already trusted ✅\");\n    return;\n  }\n\n  if (IS_WIN) {\n    await installCertWindows(certPath);\n  } else if (IS_MAC) {\n    await installCertMac(sudoPassword, certPath);\n  } else {\n    await installCertLinux(sudoPassword, certPath);\n  }\n}\n\nasync function installCertMac(sudoPassword, certPath) {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/src/mitm/cert/install.js#L70-L106","documentation":"installCert() verifies the SSL certificate file exists on disk with fs.existsSync() before attempting to add it to the system trust store. If the path does not exist, it throws immediately with the offending path in the message. This is a pre-flight guard preventing sudo/powershell commands from running against a missing file.","triggerScenarios":"Calling installCert(sudoPassword, certPath) where certPath points to a file that does not exist: CA never generated, wrong path passed, cert deleted between generation and install, or path typo.","commonSituations":"Fresh checkout where 'generate CA' step was skipped; DATA_DIR or ~/.9router moved so stored cert path is stale; running install before rootCA generation completed; passing a relative path from a different working directory.","solutions":["Generate the root CA first (run the rootCA generate routine) so the cert file exists on disk","Verify the certPath passed to installCert is the actual on-disk .crt/.pem path","Check fs.existsSync(certPath) before calling installCert and log the resolved absolute path","If the path is derived from config/env (e.g. DATA_DIR), confirm the same value used at generation time"],"exampleFix":"// before\nawait installCert(sudoPassword, certPath);\n\n// after\nif (!fs.existsSync(certPath)) {\n  await generateRootCA(); // ensure cert exists first\n}\nawait installCert(sudoPassword, certPath);","handlingStrategy":"validation","validationCode":"import fs from 'fs';\nif (!fs.existsSync(certPath)) {\n  throw new Error(`Cannot install: cert file missing at ${certPath}. Generate the CA first.`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await installCert(sudoPassword, certPath);\n} catch (e) {\n  if (e.message.startsWith('Certificate file not found')) {\n    await generateRootCA();\n    await installCert(sudoPassword, certPath);\n  } else throw e;\n}","preventionTips":["Always run CA generation as a prerequisite of cert installation","Log the resolved absolute cert path before installing","Re-check fs.existsSync after any DATA_DIR or environment change"],"tags":["filesystem","certificate","missing-file"],"backgroundTag":"certificate-file-not-found","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}