{"record":{"id":"49d0f21f3286f9e7","repo":"jdx/mise","slug":"packslip-list-identity-prefix-requires-an-issuer","errorCode":null,"errorMessage":"packslip: list_identity_prefix requires an issuer","messagePattern":"packslip: list_identity_prefix requires an issuer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/backend/packslip.rs","lineNumber":468,"sourceCode":"        ),\n    }\n}\n\nimpl Pin {\n    /// A vendor may publish its index from a different workflow than its bundles.\n    /// The override replaces only the list's subject constraint, retaining the issuer.\n    fn for_release_list(&self, opts: &PackslipOptions<'_>) -> Result<Self> {\n        let Some(value) = opts.raw.opts.get(\"list_identity_prefix\") else {\n            return Ok(self.clone());\n        };\n        let Some(prefix) = value.as_str().filter(|prefix| !prefix.trim().is_empty()) else {\n            bail!(\"packslip: list_identity_prefix must be a non-empty string\");\n        };\n        let Self::Identity(policy) = self else {\n            bail!(\"packslip: list_identity_prefix cannot be combined with pubkey\");\n        };\n        if policy.issuer.as_deref().is_none_or(str::is_empty) {\n            bail!(\"packslip: list_identity_prefix requires an issuer\");\n        }\n        Ok(Self::Identity(Policy {\n            issuer: policy.issuer.clone(),\n            identity: None,\n            identity_prefix: Some(prefix.to_string()),\n        }))\n    }\n\n    fn trust(&self) -> Trust<'_> {\n        match self {\n            Pin::Identity(policy) => Trust::Identity(policy),\n            Pin::Key(key) => Trust::Key(key),\n        }\n    }\n}\n\n/// Verify a bundle and, for each artifact path given, its digest and size.\n/// Blocks: packslip drives sigstore on a runtime of its own.","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/backend/packslip.rs#L450-L486","documentation":"When applying the `list_identity_prefix` override, the identity policy must carry an issuer, because a prefix is only meaningful relative to a trusted certificate issuer. If the policy has no issuer (or an empty one), mise cannot scope the prefix and bails with this error instead of performing unverifiable trust narrowing.","triggerScenarios":"Calling `release_list`/`github_list` where the policy is `Policy::Identity` but `policy.issuer` is `None` or an empty string, and the options set `list_identity_prefix`.","commonSituations":"A config specifies an identity prefix without the `issuer` field (e.g. the vendor's docs only give the prefix and the user omits the issuer); an issuer set via a template/env var resolves to empty.","solutions":["Add the required `issuer` to the identity policy alongside `list_identity_prefix`","Verify the issuer value isn't being rendered as an empty string by templating","Drop `list_identity_prefix` if you intend to trust the whole identity policy without prefix narrowing"],"exampleFix":"// before\n[tools.\"packslip:acme\"]\nlist_identity_prefix = \"acme\"\n// after\n[tools.\"packslip:acme\"]\nissuer = \"https://fulcio.example.com\"\nlist_identity_prefix = \"acme\"","handlingStrategy":"validation","validationCode":"if cfg.list_identity_prefix != null && (cfg.issuer == null || cfg.issuer == \"\") {\n    throw new Error(\"list_identity_prefix requires an issuer\");\n}","typeGuard":"fn has_issuer(policy: &Policy) -> bool {\n    matches!(policy, Policy::Identity { issuer: Some(i), .. } if !i.is_empty())\n}","tryCatchPattern":null,"preventionTips":["Always set both issuer and list_identity_prefix together","Verify templated issuer values are non-empty before committing config","Test `mise install` in CI so missing issuer fields surface early"],"tags":["packslip","config","validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}