Skip to content

fix(payment-actions): disambiguate action.ready result - #730

Open
pranshu-10 wants to merge 2 commits into
Universal-Commerce-Protocol:mainfrom
pranshu-10:fix/action-ready-result-schema
Open

fix(payment-actions): disambiguate action.ready result#730
pranshu-10 wants to merge 2 commits into
Universal-Commerce-Protocol:mainfrom
pranshu-10:fix/action-ready-result-schema

Conversation

@pranshu-10

@pranshu-10 pranshu-10 commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Description

Constrains the successful action.ready result to an empty object.

Problem

The action.ready result uses oneOf for:

  1. An empty success acknowledgement.
  2. An error_response.

The success branch previously accepted any JSON object. A valid error response therefore matched both branches, causing oneOf validation to fail.

Fix

Add maxProperties: 0 to the success branch so that only {} is accepted as a successful acknowledgement.

Verification

  • Empty success object {} remains valid.
  • Valid error_response objects now match only the error branch.
  • Invalid non-empty success objects are rejected.

Category (Required)

Please select one or more categories that apply to this change.

  • Core Protocol: Changes to the base communication layer, global context, or breaking refactors. (Requires Technical Council approval)
  • Governance/Contributing: Updates to GOVERNANCE.md, CONTRIBUTING.md, or CODEOWNERS. (Requires Governance Council approval)
  • Capability: New schemas (Discovery, Cart, etc.) or extensions. (Requires Maintainer approval)
  • Documentation: Updates to README, or documentations regarding schema or capabilities. (Requires Maintainer approval)
  • Infrastructure: CI/CD, Linters, or build scripts. (Requires DevOps Maintainer approval)
  • Maintenance: Version bumps, lockfile updates, or minor bug fixes. (Requires DevOps Maintainer approval)
  • SDK: Language-specific SDK updates and releases. (Requires DevOps Maintainer approval)
  • Samples / Conformance: Maintaining samples and the conformance suite. (Requires Maintainer approval)
  • UCP Schema: Changes to the ucp-schema tool (resolver, linter, validator). (Requires Maintainer approval)
  • Community Health (.github): Updates to templates, workflows, or org-level configs. (Requires DevOps Maintainer approval)

Related Issues

N/A — this PR fixes a directly identified schema validation bug.

Checklist

  • I have followed the Contributing Guide (including Conventional Commits title requirements and ! for breaking changes).
  • I have updated the documentation (if applicable).
  • My changes pass all local linting and formatting checks.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • (For Core/Capability) I have included/updated the relevant JSON schemas.
  • I have regenerated Python Pydantic models by running generate_models.sh under python_sdk.

Screenshots / Logs (if applicable)

import copy
import json
import subprocess
from pathlib import Path

from jsonschema import Draft202012Validator
from referencing import Registry, Resource

repo = Path.cwd()
filename = "source/services/payment-actions/embedded.openrpc.json"
error_schema_id = "https://ucp.dev/schemas/common/types/error_response.json"

registry = Registry()

for path in (repo / "source/schemas").rglob("*.json"):
    document = json.loads(path.read_text())

    if "$id" in document:
        registry = registry.with_resource(
            document["$id"],
            Resource.from_contents(document),
        )

error = {
    "ucp": {
        "version": "2026-08-14",
        "status": "error",
    },
    "messages": [
        {
            "type": "error",
            "code": "payment_failed",
            "content": "Authentication failed",
            "severity": "unrecoverable",
        }
    ],
}

samples = {
    "empty success": {},
    "valid error": error,
    "unexpected object": {"unexpected": True},
}

for revision in ("HEAD^", "HEAD"):
    document = json.loads(
        subprocess.check_output(
            ["git", "show", f"{revision}:{filename}"],
            text=True,
        )
    )

    schema = copy.deepcopy(
        next(
            method["result"]["schema"]
            for method in document["methods"]
            if method["name"] == "action.ready"
        )
    )

    # Resolve the OpenRPC relative reference through the local registry.
    schema["oneOf"][1]["$ref"] = error_schema_id

    validator = Draft202012Validator(schema, registry=registry)

    print(f"\n{revision}")

    for name, value in samples.items():
        print(f"  {name}: {validator.is_valid(value)}")

Used the above python script to validate following test cases for before and after the fix

1. Valid empty success

 {}

Expected:

Before fix: PASS
After fix: PASS

2. Valid error response

  {
    "ucp": {
      "version": "2026-08-14",
      "status": "error"
    },
    "messages": [
      {
        "type": "error",
        "code": "payment_failed",
        "content": "Authentication failed",
        "severity": "unrecoverable"
      }
    ]
  }

Expected:

Before fix: FAIL incorrectly
After fix: PASS

3. Invalid non-empty acknowledgement

  {
    "unexpected": true
  }

Expected:

Before fix: PASS incorrectly
After fix: FAIL

image

@pranshu-10
pranshu-10 force-pushed the fix/action-ready-result-schema branch from 98db4e3 to 6480a78 Compare August 14, 2026 18:17
@pranshu-10
pranshu-10 marked this pull request as ready for review August 14, 2026 18:59
@damaz91 damaz91 added the status:needs-triage Signal that the PR is ready for human triage label Aug 14, 2026
@damaz91 damaz91 removed the status:needs-triage Signal that the PR is ready for human triage label Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants