Skip to content

Conversation

@richmolj
Copy link
Contributor

It's helpful for Platforms to understand certain error codes and handle these scenarios with first-class treatment. Consider:

  • last_name_required: No problem, maps to input field so can be handled with generic form validation
  • payment_required: No problem, buyer hasn't reached this step yet
  • insufficient_stock: No problem, business can allocate what's possible and give warning message on remaining quantity
  • OUT_OF_STOCK: Problem! Platform may want to handle this immediately with a modal (e.g. create_checkout), only show in their Cart page UX (item goes out of stock some time after adding to cart), or elsewise provide specific/appropriate UX for this critical scenario.

Without this, Platforms need to understand each merchant's bespoke error code implementation. A small set of codes with first-class treatment is in the best interest of both merchant and buyer.

Given we also want merchant-defined codes, this cannot be an enum and is only defined in documentation.

This is not an exhaustive list, just a basic setup. PR reviewers: please note any other low-hanging fruit.

Alt: A more generic pattern was considered, combining error messages with additional metadata. This approach seemed error-prone and higher-effort, and is not mutually exclusive with first-class errors if we want to add it down the line.

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing
    functionality to not work as expected, including removal of schema files
    or fields
    )
  • Documentation update

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • 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
  • Any dependent changes have been merged and published in downstream modules

@richmolj richmolj requested a review from a team January 30, 2026 17:11
@richmolj richmolj force-pushed the lr/first-class-errors branch from d9df3c2 to d5c195b Compare January 30, 2026 17:28
@raginpirate
Copy link
Contributor

@richmolj Why not codify this? Thinking something like: bf70b4d

It sounds like you considered something much more verbose as an alternative, but I think we can still ship something against the schemas here in a non-breaking way that prevents docs taking responsibility of communicating what certain strings mean for the code field 😄

@richmolj richmolj force-pushed the lr/first-class-errors branch from d5c195b to fa3d6cc Compare January 30, 2026 21:27
@richmolj
Copy link
Contributor Author

@raginpirate good call, updated!

@yanheChen
Copy link
Contributor

naive qq here because we are talking about the error codes in EP transport as well. How do we envision the name "first party"?

  1. does first party indicate first party code existing in all flows in UCP cross all transport or first party means that this code needs proper UX handling?
  2. for the name of those code, how did you think ENUM comparing with plain text constants?

Copy link
Contributor

@raginpirate raginpirate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 🚀

@raginpirate
Copy link
Contributor

for the name of those code, how did you think ENUM comparing with plain text constants?

My proposal for encoding this used consts just because you can have descriptions alongside consts, which I feel is really nice for documenting error codes, allowing us to move some of this context out of docs and right into the schema.
I'd say this is the right direction, but I'm open to pushback on this 😄

"$id": "https://ucp.dev/schemas/shopping/types/error_code.json",
"title": "Error Code",
"description": "Error code identifying the type of error. First-class errors have standardized semantics; freeform codes are also permitted.",
"oneOf": [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work.

oneOf requires exactly one match. "out_of_stock" matches both its const AND type: string and validation will fail for any const we define here. In theory, anyOf walks around that, but it renders all the branches redundant because type: string will match everything regardless.

Suggestion:

   "description": "Error code identifying the type of error. First-class errors have standardized semantics; freeform codes are also permitted.",
    "type": "string",
    "examples": [
      "out_of_stock",
      "item_unavailable",
      "address_undeliverable",
      "payment_failed"
    ]

examples is a no-op at validation time but it's a built-in annotation for tooling that matches content in the spec.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah good catch, yes the intention was to write this as an anyOf!
Sounds like you're just disagreeing with the premise here: #147 (comment). The intention is not to actually improve static typing; a const is obviously a string, its to co-locate context about different error codes in the schema. Examples doesn't do this by default: its unclear if those examples are just random strings which obviously I can use as an error code, or if they have specific meaning for implementation.

We can solve this via comments in this file, or we can solve it via anyOf consts + fallback string, or we can choose to just let external docs deal with informing implementers they must do something special for these codes. IMO I like this solution because it nudges implementers looking at schemas in the right direction, rather than docs they may never read, but comments over examples can too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with Daniel but don't have a strong opinion. Updated to Ilya's approach since this is not a one-way door.

@igrigorik igrigorik added this to the Working Draft milestone Feb 3, 2026
@richmolj richmolj force-pushed the lr/first-class-errors branch from fa3d6cc to c6e0bef Compare February 5, 2026 14:56
@richmolj
Copy link
Contributor Author

richmolj commented Feb 5, 2026

@yanheChen

  1. Updated to "standard errors" but the intention was special UX handling by the Platform.
  2. There's some discussion about enum vs string above.

Copy link
Contributor

@igrigorik igrigorik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 modulo wording suggestion.

"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://ucp.dev/schemas/shopping/types/error_code.json",
"title": "Error Code",
"description": "Error code identifying the type of error. Standard errors have standardized semantics; freeform codes are also permitted.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"description": "Error code identifying the type of error. Standard errors have standardized semantics; freeform codes are also permitted.",
"description": "Error code identifying the type of error. Standard errors are defined in specification (see examples), and have standardized semantics; freeform codes are permitted.",

@richmolj richmolj force-pushed the lr/first-class-errors branch from a2bcc13 to 1d0e963 Compare February 10, 2026 20:45
@richmolj richmolj merged commit 5ed5b42 into main Feb 12, 2026
12 checks passed
@richmolj richmolj deleted the lr/first-class-errors branch February 12, 2026 01:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants