Skip to content

AIP-193: how should structured context be attached to PreconditionFailure #1616

@yordis

Description

@yordis

I am trying to apply AIP-193 correctly. I am not asking to change PreconditionFailure or any other Google RPC error detail type. I want to understand which existing part of google.rpc.Status.details should carry each piece of a state-based error.

The ambiguity

AIP-193 says every error response includes ErrorInfo, and that dynamic values used in error messages must also be present in ErrorInfo.metadata.

For state-based failures, PreconditionFailure appears to be the standard detail type. However, each violation only has:

message Violation {
  string type = 1;
  string subject = 2;
  string description = 3;
}

That works well for identifying and describing the violated condition, but it does not directly answer where structured context should go when the failed condition has values a client may care about, such as:

requestedUnits = 100
availableUnits = 10
reservedUnits = 90
totalInventory = 100

Concrete example

Suppose a reservation request fails because the caller requested more inventory than is currently available.

Is this the intended shape?

Status {
  code: FAILED_PRECONDITION
  message: "Insufficient inventory to complete reservation"
  details: [
    PreconditionFailure {
      violations: [{
        type: "INVENTORY_INSUFFICIENT"
        subject: "products/12345"
        description: "Cannot reserve 100 units: only 10 units available"
      }]
    },
    ErrorInfo {
      reason: "INVENTORY_INSUFFICIENT"
      domain: "inventory.example.com"
      metadata: {
        "requestedUnits": "100",
        "availableUnits": "10",
        "reservedUnits": "90",
        "totalInventory": "100"
      }
    }
  ]
}

My current interpretation is:

  1. Status.code says the broad error category: FAILED_PRECONDITION.
  2. ErrorInfo.reason and ErrorInfo.domain identify the stable machine-readable error.
  3. ErrorInfo.metadata carries scalar dynamic context that clients may use programmatically, especially values that appear in human-readable messages.
  4. PreconditionFailure describes the violated condition and affected subject, but its description remains human-readable text.
  5. A separate domain-specific detail should only be added when the client needs richer typed context that does not fit the standard details or scalar metadata.

Is that interpretation correct?

Specific questions

  1. For a FAILED_PRECONDITION response with PreconditionFailure, should scalar context such as requestedUnits and availableUnits be modeled in ErrorInfo.metadata?
  2. Should PreconditionFailure.Violation.type usually match ErrorInfo.reason, or are those fields intended to describe different levels of the error?
  3. If a value appears in PreconditionFailure.Violation.description, should it also appear in ErrorInfo.metadata?
  4. When context is too rich for ErrorInfo.metadata, is the expected pattern to attach a domain-specific detail message alongside ErrorInfo and PreconditionFailure?
  5. If a domain-specific detail is included, should overlapping scalar values still be repeated in ErrorInfo.metadata, or should clients read them only from the typed detail?
  6. For cases such as duplicate resource creation, should the status code remain ALREADY_EXISTS with appropriate details, rather than being represented as FAILED_PRECONDITION just because it depends on existing system state?

The goal is to define a service convention that follows the existing Google RPC error model and avoids making clients parse human-readable text or depend on the wrong part of the error response.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions