microsoft/typescript-go · error

Signed file has no macOS entitlements: ${filePath}

Error message

Signed file has no macOS entitlements: ${filePath}

What it means

verifyTypeScriptMacEntitlements runs `go tool quill describe --output json` on a signed darwin binary and expects an entitlements blob (details[0].superBlob.entitlements.entitlements as a string). If the binary carries no entitlements at all (unsigned, or signed without an entitlements plist), verification throws.

Source

Thrown at Herebyfile.mjs:1513

    return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
${entries}
</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

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Sign macOS binaries with the standard entitlements plist before running verification
  2. Run `go tool quill describe <file>` manually and confirm an entitlements blob is present
  3. Pin or update quill to the version whose JSON schema the script parses
Defensive patterns

Strategy: validation

Validate before calling

import { $ } from "execa";
const { stdout } = await $`go tool quill describe --quiet --output json ${filePath}`;
const hasEntitlements = typeof JSON.parse(stdout)[0]?.superBlob?.entitlements?.entitlements === "string";
if (!hasEntitlements) throw new Error(`Re-sign ${filePath} with entitlements before continuing release.`);

Type guard

/** @param {unknown} d @returns {boolean} */
function hasEntitlementsBlob(d) {
  return typeof d?.[0]?.superBlob?.entitlements?.entitlements === "string";
}

Prevention

When it happens

Trigger: The macOS signing step was skipped or ran without entitlements before verification; quill's JSON schema changed so the entitlements field is absent.

Common situations: Release tasks reordered so verification precedes entitlement-signing; quill version drift changing the describe output; ad-hoc signing without entitlements.

Related errors


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