cli/cli · error

failed to unmarshal predicate: %v

Error message

failed to unmarshal predicate: %v

What it means

Thrown when json.Unmarshal(predicateJson, &predicate) fails: the statement's predicate JSON does not fit the expected Predicate schema (BuildDefinition.ExternalParameters.Workflow, InternalParameters.GitHub, RunDetails.Metadata fields). This is the realistic schema-mismatch error of the marshal/unmarshal pair.

Source

Thrown at pkg/cmd/attestation/inspect/bundle.go:96

	envelope, err := attr.Bundle.Envelope()
	if err != nil {
		return AttestationDetail{}, fmt.Errorf("failed to get envelope from bundle: %v", err)
	}

	statement, err := envelope.EnvelopeContent().Statement()
	if err != nil {
		return AttestationDetail{}, fmt.Errorf("failed to get statement from envelope: %v", err)
	}

	var predicate Predicate
	predicateJson, err := json.Marshal(statement.Predicate)
	if err != nil {
		return AttestationDetail{}, fmt.Errorf("failed to marshal predicate: %v", err)
	}

	err = json.Unmarshal(predicateJson, &predicate)
	if err != nil {
		return AttestationDetail{}, fmt.Errorf("failed to unmarshal predicate: %v", err)
	}

	org, repo, err := getOrgAndRepo(tenant, predicate.BuildDefinition.ExternalParameters.Workflow.Repository)
	if err != nil {
		return AttestationDetail{}, fmt.Errorf("failed to parse attestation content: %v", err)
	}

	return AttestationDetail{
		OrgName:        org,
		OrgID:          predicate.BuildDefinition.InternalParameters.GitHub.RepositoryOwnerId,
		RepositoryName: repo,
		RepositoryID:   predicate.BuildDefinition.InternalParameters.GitHub.RepositoryID,
		WorkflowID:     predicate.RunDetails.Metadata.InvocationID,
	}, nil
}

View on GitHub (pinned to 0eeec0b92e)

Solutions

  1. Use `gh attestation inspect` output or jq on the bundle to view the predicate's actual shape
  2. Upgrade gh to a release matching the artifact's predicate version
  3. Note that non-provenance attestations may not carry workflow fields this code expects
Defensive patterns

Strategy: type-guard

Validate before calling

raw, _ := json.Marshal(statement.Predicate)
var probe map[string]any
if err := json.Unmarshal(raw, &probe); err != nil {
	return errors.New("predicate is not valid JSON")
}
bd, ok := probe["buildDefinition"].(map[string]any)
if !ok { return errors.New("predicate lacks buildDefinition; not a provenance attestation") }

Type guard

func isProvenancePredicate(stmt *intoto.Statement) bool {
	return stmt.PredicateType == "https://slsa.dev/provenance/v1" ||
		stmt.PredicateType == "https://slsa.dev/provenance/v0.2"
}

Try / catch

if err := json.Unmarshal(predicateJson, &predicate); err != nil {
	return fmt.Errorf("predicate schema mismatch (type %s): %w", statement.PredicateType, err)
}

Prevention

When it happens

Trigger: A predicate whose buildDefinition or runDetails differs structurally from what the Predicate struct expects, e.g. missing workflow.externalParameters or unexpected JSON types (string where object expected).

Common situations: Custom predicates (not provenance), newer SLSA predicate layouts, or third-party signed statements run through `gh attestation inspect`.

Related errors


AI-assisted analysis of cli/cli@0eeec0b92e (2026-08-15). Data as JSON: /api/errors/37c2a5e0e7b4fd9a. Report an issue: GitHub.