{"record":{"id":"3357d2e6e0340472","repo":"hashicorp/packer","slug":"decode-slsa-predicate-for-policy-verification-w","errorCode":null,"errorMessage":"decode SLSA predicate for policy verification: %w","messagePattern":"decode SLSA predicate for policy verification: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/verify.go","lineNumber":252,"sourceCode":"\tif policy.ArtifactPath != \"\" {\n\t\tif err := verifyArtifactSubject(statement.Subject, policy.ArtifactPath); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif policy.BuilderID != \"\" || policy.SourceURI != \"\" {\n\t\tif statement.PredicateType != internalprovenance.SLSAProvenanceV1PredicateType {\n\t\t\treturn nil, fmt.Errorf(\"builder and source policy checks require predicate type %q, got %q\", internalprovenance.SLSAProvenanceV1PredicateType, statement.PredicateType)\n\t\t}\n\n\t\tvar typedStatement struct {\n\t\t\tType          string                                     `json:\"_type\"`\n\t\t\tSubject       []internalprovenance.Subject               `json:\"subject\"`\n\t\t\tPredicateType string                                     `json:\"predicateType\"`\n\t\t\tPredicate     internalprovenance.SLSAProvenancePredicate `json:\"predicate\"`\n\t\t}\n\t\tif err := json.Unmarshal(payload, &typedStatement); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"decode SLSA predicate for policy verification: %w\", err)\n\t\t}\n\n\t\tif policy.BuilderID != \"\" && typedStatement.Predicate.RunDetails.Builder.ID != policy.BuilderID {\n\t\t\treturn nil, fmt.Errorf(\"attestation builder id %q does not match expected %q\", typedStatement.Predicate.RunDetails.Builder.ID, policy.BuilderID)\n\t\t}\n\n\t\tif policy.SourceURI != \"\" {\n\t\t\tmatched := false\n\t\t\tfor _, dependency := range typedStatement.Predicate.BuildDefinition.ResolvedDependencies {\n\t\t\t\tif dependency.URI == policy.SourceURI {\n\t\t\t\t\tmatched = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !matched {\n\t\t\t\treturn nil, fmt.Errorf(\"attestation does not contain expected source URI %q\", policy.SourceURI)\n\t\t\t}\n\t\t}","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/verify.go#L234-L270","documentation":"After confirming the statement is SLSA provenance v1, verifyPolicy re-decodes the payload into a typed structure that includes the SLSAProvenancePredicate. This error wraps any JSON decoding failure of that typed structure, e.g. when the predicate object is missing, not an object, or its fields (runDetails, buildDefinition) have incompatible shapes.","triggerScenarios":"VerifyAttestationFile with a policy containing BuilderID or SourceURI, on an attestation whose predicateType claims v1 but whose predicate body is absent, null, or does not match the SLSA v1 schema (wrong nesting, wrong field types).","commonSituations":"Hand-crafted or tool-mangled attestations that label themselves v1 but omit the predicate; predicates following an incompatible draft schema; corrupted/truncated JSON files.","solutions":["Inspect the attestation's `predicate` field; ensure it exists and follows the SLSA provenance v1 schema (buildDefinition, runDetails).","Regenerate the attestation with an up-to-date, spec-compliant producer.","Validate the attestation against the SLSA v1 JSON schema before verification.","Check the underlying wrapped decode error (%w) for the exact JSON path/type that failed."],"exampleFix":"// before\n{\"predicateType\":\"https://slsa.dev/provenance/v1\"} // predicate missing\n// after\n{\"predicateType\":\"https://slsa.dev/provenance/v1\",\"predicate\":{\"buildDefinition\":{...},\"runDetails\":{...}}}","handlingStrategy":"type-guard","validationCode":"var s struct {\n\tPredicateType string `json:\"predicateType\"`\n\tPredicate     struct {\n\t\tRunDetails      json.RawMessage `json:\"runDetails\"`\n\t\tBuildDefinition json.RawMessage `json:\"buildDefinition\"`\n\t} `json:\"predicate\"`\n}\nif err := json.Unmarshal(payload, &s); err != nil || len(s.Predicate.RunDetails) == 0 {\n\treturn fmt.Errorf(\"malformed SLSA v1 predicate\")\n}","typeGuard":"func hasSLSAV1PredicateShape(payload []byte) bool {\n\tvar s struct {\n\t\tPredicate struct {\n\t\t\tRunDetails      json.RawMessage `json:\"runDetails\"`\n\t\t\tBuildDefinition json.RawMessage `json:\"buildDefinition\"`\n\t\t} `json:\"predicate\"`\n\t}\n\treturn json.Unmarshal(payload, &s) == nil && s.Predicate.RunDetails != nil && s.Predicate.BuildDefinition != nil\n}","tryCatchPattern":"_, err := VerifyAttestationFile(path, policy)\nif err != nil && strings.Contains(err.Error(), \"decode SLSA predicate\") {\n\tvar syntaxErr *json.SyntaxError\n\tif errors.As(err, &syntaxErr) {\n\t\tlog.Printf(\"bad JSON at offset %d\", syntaxErr.Offset)\n\t}\n}","preventionTips":["Validate attestations against the SLSA v1 JSON schema before verification","Never hand-edit attestation JSON","Check the wrapped %w error for the failing JSON path"],"tags":["attestation","slsa","json-decoding"],"backgroundTag":"slsa-predicate-decode-failed","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}