micro/go-micro · error

ap2: marshal mandate: %w

Error message

ap2: marshal mandate: %w

What it means

ap2Payload canonicalizes an AP2Mandate by JSON-marshaling it and hashing with SHA-256 to produce the bytes that are signed/verified. This error is returned if json.Marshal fails on the mandate — practically only when the mandate contains a value that cannot be marshaled (e.g. a channel, func, or cyclic structure in a custom field). It wraps the marshal error with %w and is reached from both SignAP2Mandate and VerifyAP2Mandate.

Source

Thrown at gateway/a2a/ap2.go:146

		return out
	}
	if s.Mandate.Kind == AP2PaymentMandate && rail != nil {
		if s.Mandate.Rail == nil || *s.Mandate.Rail != *rail {
			out.Verified = false
			out.Error = "ap2: settlement rail reference mismatch"
			return out
		}
	}
	return out
}

// X402AP2Rail builds the x402 settlement rail reference carried under a payment mandate.
func X402AP2Rail(reference string) AP2RailRef { return AP2RailRef{Type: "x402", Reference: reference} }

func ap2Payload(m AP2Mandate) ([]byte, error) {
	b, err := json.Marshal(m)
	if err != nil {
		return nil, fmt.Errorf("ap2: marshal mandate: %w", err)
	}
	sum := sha256.Sum256(b)
	return sum[:], nil
}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Inspect the wrapped json error to identify the offending field; remove or replace func/channel/cyclic values with marshalable data (strings, numbers).
  2. Ensure any custom MarshalJSON on mandate sub-types cannot return an error for valid mandates.
  3. Normalize metadata to plain JSON-safe types (map[string]string / encoding/json-compatible structs) before signing.

Example fix

// before
m := ap2.AP2Mandate{Meta: map[string]any{"cb": make(chan int)}}
// after
m := ap2.AP2Mandate{Meta: map[string]any{"note": "hello"}}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := json.Marshal(mandate); err != nil {
    return fmt.Errorf("mandate not marshallable: %w", err)
}

Try / catch

err := a2a.VerifyAP2Mandate(signed, pub)
if err != nil && strings.Contains(err.Error(), "marshal mandate") {
    // inspect the wrapped json error and fix the un-marshalable field
}

Prevention

When it happens

Trigger: Calling SignAP2Mandate or VerifyAP2Mandate with an AP2Mandate whose fields (or nested custom fields) contain un-marshalable Go values, causing 'ap2: marshal mandate: <json error>'.

Common situations: Embedding a func or channel in a custom/extension field of the mandate; a cyclic data structure in user metadata; using a custom MarshalJSON that itself errors.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/005fc7ec2afed89a. Report an issue: GitHub.