jdx/mise · error

packslip: list_identity_prefix cannot be combined with…

Error message

packslip: list_identity_prefix cannot be combined with pubkey

What it means

`list_identity_prefix` only refines an identity-based (Sigstore identity) trust policy. If the pin was built from a raw `pubkey`, there is no identity to retain an issuer from, so combining the two options is rejected as contradictory.

Solutions

  1. Remove `pubkey` and pin via `identity` (or `identity` + `issuer`) instead if you want to use list_identity_prefix.
  2. Remove `list_identity_prefix` if you intend to trust via the raw public key.
  3. Keep the two tools' configs separate — one pubkey-pinned tool and one identity-pinned tool cannot share these options.

Example fix

// before
"packslip:foo" = { version = "1.0", pubkey = "...", list_identity_prefix = "https://github.com/vendor/" }

// after
"packslip:foo" = { version = "1.0", identity = "release@vendor.example", issuer = "https://token.actions.githubusercontent.com", list_identity_prefix = "https://github.com/vendor/" }
Defensive patterns

Strategy: validation

Validate before calling

function validateTrustOptions(opts) {
  if (opts.pubkey && opts.list_identity_prefix !== undefined) {
    throw new Error('list_identity_prefix cannot be combined with pubkey');
  }
}

Prevention

When it happens

Trigger: Configuring a packslip tool with both `pubkey` and `list_identity_prefix`, then calling release_list or github_list (for_release_list override).

Common situations: Copy-pasting trust options from two different examples; a vendor migrating from pubkey pinning to keyless Sigstore identities while the user keeps both options.

Related errors


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

Appendix: source

Thrown at src/backend/packslip.rs:569

        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");
        };
        if policy.issuer.as_deref().is_none_or(str::is_empty) {
            bail!("packslip: list_identity_prefix requires an issuer");
        }
        Ok(Self::Identity(Policy {
            issuer: policy.issuer.clone(),
            identity: None,
            identity_prefix: Some(prefix.to_string()),
        }))
    }

    fn trust(&self) -> Trust<'_> {
        match self {
            Pin::Identity(policy) => Trust::Identity(policy),
            Pin::Key(key) => Trust::Key(key),
        }
    }
}

View on GitHub (pinned to 533346cc37)