jdx/mise · error

packslip.stampers entry

Error message

packslip.stampers entry {spec:?} has no pin; write host=PUBKEY, host=path/to/key.pub, or host=https://github.com/org/repo/

What it means

Raised by packslip_stamps::Stamper::parse when a `packslip.stampers` entry does not contain an '=' separator. A stamper entry must be written as `host=PIN`, where the pin is either a minisign public key line, a path to a .pub file, or an https:// GitHub identity prefix. Without '=', no host or pin can be extracted.

Solutions

  1. Rewrite the entry as host=PIN: e.g. "example.com=path/to/key.pub" or "example.com=<minisign public key line>".
  2. For a keyless GitHub signer, use the identity-prefix form, e.g. "example.com=https://github.com/org/repo/".
  3. Check for typos — the '=' must be present even if the pin is a path or URL.

Example fix

// before (mise.toml)
[packslip]
stampers = ["example.com"]
// after
[packslip]
stampers = ["example.com=https://github.com/org/repo/"]
Defensive patterns

Strategy: validation

Validate before calling

// validate stamper entries before writing them to config
function isValidStamperEntry(spec) {
  return typeof spec === "string" && spec.includes("=") && spec.trim().length > 0;
}

Type guard

function isHostPinPair(spec) {
  if (typeof spec !== "string") return false;
  const i = spec.indexOf("=");
  return i > 0 && i < spec.length - 1;
}

Try / catch

try {
  parseStamper(spec);
} catch (e) {
  if (String(e).includes("has no pin")) {
    throw new Error(`Fix ${spec}: use host=PUBKEY, host=path/to/key.pub, or host=https://github.com/org/repo/`);
  } else throw e;
}

Prevention

When it happens

Trigger: Parsing a stampers config entry (e.g. `packslip.stampers = ["github.com"]` or a value with no '=' at all) via Stamper::parse — the split_once('=') returns None.

Common situations: Writing only the host name in mise.toml and forgetting the '=pubkey' part; pasting a bare public key without prefixing the host; quoting or whitespace mistakes that drop the '='.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/packslip_stamps.rs:49

use crate::toolset::ToolVersionOptions;

/// GitHub's OIDC issuer, for a stamper pinned by a workflow identity.
const GITHUB_ISSUER: &str = "https://token.actions.githubusercontent.com";

/// A host whose stamps mise trusts, and how its lists are pinned.
pub(crate) struct Stamper {
    pub(crate) host: String,
    pin: Pin,
}

impl Stamper {
    /// `host=PIN`, where PIN is a minisign public key line, the path of a
    /// `.pub` file, or an `https://` identity prefix for a keyless signer
    /// on GitHub such as `https://github.com/org/registry/`.
    pub(crate) fn parse(spec: &str) -> Result<Stamper> {
        let spec = spec.trim();
        let Some((host, pin)) = spec.split_once('=') else {
            bail!(
                "packslip.stampers entry {spec:?} has no pin; write host=PUBKEY, host=path/to/key.pub, or host=https://github.com/org/repo/"
            );
        };
        let host = host.trim();
        let pin = pin.trim();
        if host.is_empty() || !host.contains('.') || host.contains('/') {
            bail!("packslip.stampers entry {spec:?}: {host:?} is not a host name");
        }
        let pin = if pin.starts_with("https://") {
            Pin::Identity(Policy {
                issuer: Some(GITHUB_ISSUER.into()),
                identity: None,
                identity_prefix: Some(pin.to_string()),
            })
        } else {
            let text = if std::path::Path::new(pin).is_file() {
                file::read_to_string(pin)?
            } else {

View on GitHub (pinned to 533346cc37)