{"record":{"id":"e0ae87de054fb8d0","repo":"microsoft/typescript-go","slug":"unknown-cert-cert","errorCode":null,"errorMessage":"Unknown cert: ${cert}","messagePattern":"Unknown cert: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"Herebyfile.mjs","lineNumber":2104,"sourceCode":"                    const zip = new AdmZip();\r\n                    zip.addLocalFile(p.path);\r\n                    zip.writeZip(unsignedZipPath);\r\n\r\n                    macZips.push({\r\n                        path: p.path,\r\n                        unsignedZipPath,\r\n                        signedZipPath,\r\n                        notarizedZipPath,\r\n                    });\r\n                }\r\n                filelist.SignFileRecordList.push({\r\n                    SignFileList: macZips.map(p => ({ SrcPath: p.unsignedZipPath, DstPath: p.signedZipPath })),\r\n                    Certs: cert,\r\n                    MacAppName: undefined, // MacAppName is only for notarization\r\n                });\r\n                break;\r\n            default:\r\n                throw new Error(`Unknown cert: ${cert}`);\r\n        }\r\n    }\r\n\r\n    await sign(filelist);\r\n\r\n    // All of the files have been signed in place / had signatures added.\r\n\r\n    if (macZips.length) {\r\n        // Now, notarize the Mac files.\r\n\r\n        /** @type {DDSignFileList} */\r\n        const notarizeFilelist = {\r\n            SignFileRecordList: [\r\n                {\r\n                    SignFileList: macZips.map(p => ({ SrcPath: p.signedZipPath, DstPath: p.notarizedZipPath })),\r\n                    Certs: \"8020\", // \"MacNotarize\" (friendly name not supported by the tooling)\r\n                    MacAppName: \"MicrosoftTypeScript\",\r\n                },\r","sourceCodeStart":2086,"sourceCodeEnd":2122,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/Herebyfile.mjs#L2086-L2122","documentation":"runSignNativePreviewPackages groups the built executables by their platform `cert` and switches over the three certificate names the ESRP tooling knows: \"Microsoft400\" (Windows), \"LinuxSign\" (default for Linux/BSD per the platforms table comment at Herebyfile.mjs:1548), and \"MacDeveloperHarden\" (macOS). Any other string reaches `default` and throws because no signing recipe exists for it.","triggerScenarios":"Adding or editing a Platform entry in the `platforms` array (Herebyfile.mjs:1551-1574) with a `cert` value that is not exactly \"Microsoft400\", \"LinuxSign\", or \"MacDeveloperHarden\" — e.g. a typo like \"MS400\" or a new cert name — then running the signing task.","commonSituations":"Contributing a new platform and guessing/typoing the cert name; renaming certs during ESRP config changes; forgetting that cert is optional and defaults to LinuxSign on non-Windows/non-Mac platforms.","solutions":["Set `cert` to one of the three known values, matching the OS: Microsoft400 for win32, MacDeveloperHarden for darwin, LinuxSign otherwise","If the platform needs no special signing, omit `cert` entirely — the platform mapping defaults it to LinuxSign","If a genuinely new certificate is required, add a matching `case` to the switch in runSignNativePreviewPackages plus the ESRP configuration, then re-run"],"exampleFix":"// before\n{ os: \"win32\", arch: \"x64\", vsix: true, cert: \"MS400\" },\n\n// after\n{ os: \"win32\", arch: \"x64\", vsix: true, cert: \"Microsoft400\" },","handlingStrategy":"type-guard","validationCode":"const knownCerts = [\"Microsoft400\", \"LinuxSign\", \"MacDeveloperHarden\"];\nfor (const p of platforms) {\n  const cert = p.cert ?? \"LinuxSign\";\n  if (!knownCerts.includes(cert)) throw new Error(`Invalid cert on ${p.os}-${p.arch}: ${cert}`);\n}","typeGuard":"const knownCerts = [\"Microsoft400\", \"LinuxSign\", \"MacDeveloperHarden\"] as const;\ntype Cert = typeof knownCerts[number];\nfunction isKnownCert(c: string): c is Cert {\n  return (knownCerts as readonly string[]).includes(c);\n}","tryCatchPattern":null,"preventionTips":["Derive the Cert JSDoc union and the switch cases from one shared list so a new cert forces both updates","Omit cert for platforms that use the LinuxSign default instead of spelling it"],"tags":["build","release","signing","configuration","esrp"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}