jdx/mise · error

packslip: is not on a forge mise knows, so nothing pins its…

Error message

packslip:{project} is not on a forge mise knows, so nothing pins its signer; set `pubkey`, or `identity` and `issuer`, in its tool options

What it means

Packslip verifies artifacts against a signer pinned by a Sigstore identity. If the project is not on a forge mise knows (so no built-in trust policy applies) and the user supplied no `pubkey` or `identity`/`issuer` tool options, nothing pins the signer, so mise refuses to trust any artifact rather than accepting arbitrary signers.

Solutions

  1. Add trust options in mise.toml: "packslip:foo" = { version = "x", pubkey = "-----BEGIN PUBLIC KEY-----..." }.
  2. Or pin a Sigstore identity: identity = "release@vendor.example" and issuer = "https://token.actions.githubusercontent.com".
  3. Verify the project name is spelled exactly as the vendor's packslip project id.
  4. Check for a mise update — the vendor may have been added to the built-in policy list.

Example fix

// before
[tools]
"packslip:foo" = "1.2.0"

// after
[tools]
"packslip:foo" = { version = "1.2.0", identity = "release@vendor.example", issuer = "https://token.actions.githubusercontent.com" }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure trust options exist before installing an unknown packslip project.
const KNOWN_FORGES = ['github.com', 'gitlab.com'];
function hasTrustOption(opts) {
  return Boolean(opts.pubkey || (opts.identity && opts.issuer));
}
if (!KNOWN_FORGES.some(f => projectUrl.startsWith(f)) && !hasTrustOption(toolOpts)) {
  throw new Error('configure pubkey or identity+issuer for this packslip project');
}

Prevention

When it happens

Trigger: Installing a packslip:project tool where Policy::for_project returns None and neither `pubkey` nor `identity`+`issuer` options were configured; hit from vendor_versions, install_payload, latest_version, or lock resolution.

Common situations: Using a packslip for a self-hosted or niche project not in mise's known-forge policy list; typo'd project name so the policy lookup misses; a new vendor not yet added to mise's policy table.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/69cc6dc1d1a711cb. Report an issue: GitHub.

Appendix: source

Thrown at src/backend/packslip.rs:552

            file::read_to_string(&pubkey)?
        } else {
            pubkey
        };
        let key = packslip::minisign::PublicKey::parse(&text)
            .map_err(|e| eyre!("packslip:{project}: pubkey: {e}"))?;
        return Ok(Pin::Key(key));
    }
    let explicit = Policy {
        issuer: opts.issuer(),
        identity: opts.identity(),
        identity_prefix: opts.identity_prefix(),
    };
    if !explicit.is_empty() {
        return Ok(Pin::Identity(explicit));
    }
    match Policy::for_project(project) {
        Some(policy) => Ok(Pin::Identity(policy)),
        None => bail!(
            "packslip:{project} is not on a forge mise knows, so nothing pins its signer; set `pubkey`, or `identity` and `issuer`, in its tool options"
        ),
    }
}

impl Pin {
    /// A vendor may publish its index from a different workflow than its bundles.
    /// The override replaces only the list's subject constraint, retaining the issuer.
    fn for_release_list(&self, opts: &PackslipOptions<'_>) -> Result<Self> {
        let Some(value) = opts.raw.opts.get("list_identity_prefix") else {
            return Ok(self.clone());
        };
        let Some(prefix) = value.as_str().filter(|prefix| !prefix.trim().is_empty()) else {
            bail!("packslip: list_identity_prefix must be a non-empty string");
        };
        let Self::Identity(policy) = self else {
            bail!("packslip: list_identity_prefix cannot be combined with pubkey");
        };

View on GitHub (pinned to 533346cc37)