micro/go-micro · error

ap2: mandate id is required

Error message

ap2: mandate id is required

What it means

SignAP2Mandate in gateway/a2a/ap2.go validates the AP2Mandate before signing it as a verifiable credential. It refuses to sign when the mandate's ID field is empty, since a credential without a stable identifier cannot be referenced, verified, or audited by the gateway. The signature flow aborts immediately and returns an empty AP2SignedMandate alongside this error.

Source

Thrown at gateway/a2a/ap2.go:68

// AP2Verification records mandate verification on an A2A task without mixing in
// payment-settlement state.
type AP2Verification struct {
	MandateID string `json:"mandateId"`
	Kind      string `json:"kind"`
	Verified  bool   `json:"verified"`
	Error     string `json:"error,omitempty"`
}

// NewAP2Keypair returns an Ed25519 keypair suitable for tests or local demos.
func NewAP2Keypair() (ed25519.PublicKey, ed25519.PrivateKey, error) {
	return ed25519.GenerateKey(rand.Reader)
}

// SignAP2Mandate signs a mandate as a verifiable AP2 credential.
func SignAP2Mandate(m AP2Mandate, keyID string, private ed25519.PrivateKey) (AP2SignedMandate, error) {
	if m.ID == "" {
		return AP2SignedMandate{}, errors.New("ap2: mandate id is required")
	}
	if m.Kind == "" {
		return AP2SignedMandate{}, errors.New("ap2: mandate kind is required")
	}
	if m.IssuedAt.IsZero() {
		m.IssuedAt = time.Now().UTC()
	}
	payload, err := ap2Payload(m)
	if err != nil {
		return AP2SignedMandate{}, err
	}
	return AP2SignedMandate{Mandate: m, KeyID: keyID, Signature: base64.RawURLEncoding.EncodeToString(ed25519.Sign(private, payload))}, nil
}

// VerifyAP2Mandate verifies a signed mandate credential.
func VerifyAP2Mandate(s AP2SignedMandate, public ed25519.PublicKey) error {
	sig, err := base64.RawURLEncoding.DecodeString(s.Signature)
	if err != nil {

View on GitHub (pinned to 24529f1404)

Solutions

  1. Assign a unique non-empty ID to the AP2Mandate before calling SignAP2Mandate (e.g. a UUID or request-scoped identifier).
  2. If the mandate comes from JSON input, validate/require the id field at deserialization time and reject empty values early.
  3. Add a unit test or builder that guarantees ID is populated whenever a mandate is created.

Example fix

// before
m := ap2.AP2Mandate{Kind: "checkout", IssuedAt: time.Now()}
signed, err := ap2.SignAP2Mandate(m, keyID, priv)

// after
m := ap2.AP2Mandate{ID: uuid.NewString(), Kind: "checkout", IssuedAt: time.Now()}
signed, err := ap2.SignAP2Mandate(m, keyID, priv)
Defensive patterns

Strategy: validation

Validate before calling

if m.ID == "" {
	return fmt.Errorf("cannot sign mandate: ID must be set")
}

Try / catch

if _, err := ap2.SignAP2Mandate(m, keyID, priv); err != nil {
	if strings.Contains(err.Error(), "mandate id is required") {
		// regenerate or reject the mandate
	}
}

Prevention

When it happens

Trigger: Calling SignAP2Mandate(m, keyID, private) with an AP2Mandate struct whose ID field is the empty string, typically when the mandate was constructed programmatically without assigning an identifier.

Common situations: Building AP2Mandate literals in tests or tooling and forgetting to set ID; code paths that deserialize partial mandates from JSON where the id key was omitted; refactors that renamed a field so the ID assignment was dropped.

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 micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/ed990941a7d5273e. Report an issue: GitHub.