Skip to content

MCP: internal CanonicalizationError (FormatId in canonical payload hash) surfaces as buyer VALIDATION_ERROR #1679

Description

@ChrisHuie

On MCP, creating a media buy with an inline creative and an idempotency_key crashes while computing the idempotency canonical payload hash, and the internal crash is surfaced to the buyer as a correctable VALIDATION_ERROR — masking the real creative-validation rejection.

Observed (BDD BR-RULE-015 INV-6, per transport)

  • a2a / rest: the request reaches creative validation; the missing asset_type discriminator is rejected as CREATIVE_REJECTED. (The idempotency hash falls back to canonical_request_hash(req), whose model_dump(mode="json") serializes FormatId cleanly, so no crash.)
  • mcp: the transport threads the raw wire payload, so canonical_payload_hash(raw_wire_payload) runs over a payload containing a live FormatId object. rfc8785 cannot serialize it → CanonicalizationError (a ValueError subclass) → normalize_to_adcp_error maps it to AdCPValidationError. The wire carries error_code=VALIDATION_ERROR, recovery=correctable, message unsupported type: <class 'src.core.schemas._base.FormatId'> — an internal crash presented as a correctable buyer error, and the real creative-validation error never surfaces.

Trace

  • src/core/tools/media_buy_create.py:2080canonical_payload_hash(raw_wire_payload) (idempotency-replay hash, when idempotency_key is set)
  • src/core/idempotency_canonical.pycanonical_payload_hashrfc8785
  • src/core/exceptions.py (normalize_to_adcp_error) — isinstance(exc, ValueError) -> AdCPValidationError
  • caught / logged by src/core/tool_error_logging.py ("MCP boundary untyped CanonicalizationError")

Impact

  • Buyer receives a misleading correctable VALIDATION_ERROR for an internal serialization bug.
  • Masks the real creative-validation rejection on MCP.
  • Blocks graduation of the BR-RULE-015 INV-6 BDD scenario on MCP.

Suggested fix

Make the idempotency canonical hash tolerant of domain objects — serialize/coerce FormatId (and peers) in the raw wire payload before rfc8785, or hash the model-dumped form consistently across transports. Separately, avoid mapping an internal CanonicalizationError to a buyer-facing VALIDATION_ERROR.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    In Progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions