microsoft/typescript-go · error

Signed file is missing macOS entitlement '${entitlement}': $

Error message

Signed file is missing macOS entitlement '${entitlement}': ${filePath}

What it means

The entitlements XML on the signed binary must contain <key>NAME</key> followed by <true/> for every entry in typescriptMacEntitlements. A missing key, or one set to false, fails verification for that specific entitlement.

Source

Thrown at Herebyfile.mjs:1518

</dict>
</plist>
`;
}

/**
 * @param {string} filePath
 */
async function verifyTypeScriptMacEntitlements(filePath) {
    const { stdout } = await $pipe`go tool quill describe --quiet --output json ${filePath}`;
    const details = JSON.parse(stdout);
    const entitlements = details[0]?.superBlob?.entitlements?.entitlements;
    if (typeof entitlements !== "string") {
        throw new Error(`Signed file has no macOS entitlements: ${filePath}`);
    }
    for (const entitlement of typescriptMacEntitlements) {
        const escapedEntitlement = entitlement.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
        if (!new RegExp(`<key>\\s*${escapedEntitlement}\\s*</key>\\s*<true\\s*/>`).test(entitlements)) {
            throw new Error(`Signed file is missing macOS entitlement '${entitlement}': ${filePath}`);
        }
    }
}

/**
 * @typedef {"win32" | "linux" | "darwin" | "aix" | "android" | "freebsd" | "netbsd" | "openbsd" | "sunos"} OS
 * @typedef {"x64" | "arm" | "arm64" | "ia32" | "ppc64" | "loong64" | "mips64el" | "riscv64" | "s390x"} Arch
 * @typedef {"Microsoft400" | "LinuxSign" | "MacDeveloperHarden" | "8020" | "VSCodePublisher"} Cert
 * @typedef {`${OS | "alpine"}-${Exclude<Arch, "arm"> | "armhf"}`} VSCodeTarget
 * @typedef {{ name: string; sourceDir: string }} VsixExtensionPackage
 * @typedef {{ nodeOs: string; vscodeTarget: string; sourceDir: string; extensionDir: string; vsixPath: string; vsixManifestPath: string; vsixSignaturePath: string }} VsixExtension
 * @typedef {{ GOOS: string; GOARCH: string }} GoDistTarget
 * @typedef {{ os: OS; arch: Arch; cert?: Cert; vsix?: boolean; alpine?: boolean }} Platform
 */
void 0;

/** @type {VsixExtensionPackage[]} */
const vsixExtensionPackages = [

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Add the missing key as <true/> in the entitlements plist used for signing, then re-sign
  2. Or remove/adjust the entry in typescriptMacEntitlements if that entitlement is no longer required
  3. Change the plist and typescriptMacEntitlements in the same commit to keep them in sync

Example fix

<!-- before -->
<key>com.apple.security.cs.allow-jit</key>
<false/>

<!-- after -->
<key>com.apple.security.cs.allow-jit</key>
<true/>
Defensive patterns

Strategy: validation

Validate before calling

for (const entitlement of typescriptMacEntitlements) {
  const re = new RegExp(`<key>\\s*${entitlement.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*</key>\\s*<true\\s*/>`);
  if (!re.test(plistXml)) throw new Error(`Entitlements plist lacks ${entitlement}; fix before signing.`);
}

Prevention

When it happens

Trigger: A new entitlement name was added to typescriptMacEntitlements in Herebyfile.mjs without adding it (as true) to the plist used at signing time, or the plist sets that key to false.

Common situations: Drift between the expected-entitlements list in the build script and the signing plist; entitlements toggled off during debugging.

Related errors


AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16). Data as JSON: /api/errors/1e9814d89902a9e3. Report an issue: GitHub.