REST Lens
← Back to All Rules
Rule 8

Response Error Codes

Category: Response Design

Description

Error conditions should be indicated through HTTP status codes (4xx/5xx) rather than by embedding error codes in successful (2xx) response bodies.

What It Checks

This rule inspects successful (2xx) response bodies in JSON and XML formats to detect fields or properties that suggest error codes. It checks for:

  • Property names containing the word "error" (case-insensitive)
  • Schema titles containing "error"
  • Enum values with keys containing "error"
  • Nested objects and arrays within response schemas

The rule recursively traverses the entire response schema to ensure no error-related fields are present in successful responses.

Why It Matters

Using HTTP status codes properly is fundamental to RESTful API design:

  • HTTP Semantics: Status codes are the standard mechanism for indicating request outcomes
  • Client Simplification: Clients can handle errors uniformly by checking status codes without parsing response bodies
  • Middleware Compatibility: Proxies, caches, and monitoring tools rely on status codes to understand request outcomes
  • Developer Experience: Following HTTP conventions reduces cognitive load and makes APIs more intuitive

Examples

Good ✅

paths:
  /users/{userId}:
    get:
      summary: Get user by ID
      responses:
        '200':
          description: User found
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  name:
                    type: string
                  email:
                    type: string
        '404':
          description: User not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "User not found"

  /orders:
    post:
      summary: Create an order
      responses:
        '201':
          description: Order created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  orderId:
                    type: string
                  status:
                    type: string
                    enum: [pending, confirmed, shipped]
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string

Bad ❌

paths:
  /users/{userId}:
    get:
      summary: Get user by ID
      responses:
        '200':
          description: Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  errorCode:  # ❌ Error code in 2xx response
                    type: string
                  errorMessage:  # ❌ Error message in 2xx response
                    type: string
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                      name:
                        type: string

  /orders:
    post:
      summary: Create an order
      responses:
        '200':
          description: Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum: [success, error_invalid_payment, error_out_of_stock]  # ❌ Error enums in 2xx
                  orderId:
                    type: string

  /products/{id}:
    get:
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  result:
                    type: object
                    properties:
                      error:  # ❌ Nested error field in 2xx response
                        type: string
                      product:
                        type: object

Configuration

This rule has no configuration options. It is either enabled or disabled.

How to Fix

  1. Remove error-related fields from successful responses:

    # Before
    '200':
      content:
        application/json:
          schema:
            properties:
              errorCode: string  # Remove this
              data: object
    
    # After
    '200':
      content:
        application/json:
          schema:
            properties:
              data: object  # Just the success data
    
  2. Add appropriate error status codes:

    # Add 4xx/5xx responses for error cases
    '400':
      description: Invalid request
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
    
    '404':
      description: Resource not found
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
    
    '500':
      description: Internal server error
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
    
  3. Restructure envelope patterns:

    # Before (envelope with error field)
    '200':
      schema:
        properties:
          success: boolean
          errorCode: string
          data: object
    
    # After (no envelope for success)
    '200':
      schema:
        # Direct response data
        type: object
        properties:
          id: string
          name: string
    
    '400':
      schema:
        properties:
          message: string
          details: array
    
  4. Clean up enum values:

    # Before
    status:
      enum: [success, error_failed, error_timeout]
    
    # After
    status:
      enum: [pending, processing, completed]
    
    # Errors returned via 4xx/5xx status codes instead
    

Related Rules

  • Rule 6: HTTP Status Codes - Proper use of status codes for different outcomes
  • Rule 7: Response Format Consistency - Maintaining consistent response structures
  • Rule 15: Error Response Structure - Standardizing error response formats

Common Violations

  1. Envelope pattern with error fields:

    • Including errorCode, errorMessage, or error in all responses
  2. Status field anti-pattern:

    • Using status: "success" | "error" instead of HTTP status codes
  3. Nested error fields:

    • Including error information in nested objects within 2xx responses
  4. Error enums in success responses:

    • Enum values like ["success", "error_invalid", "error_failed"]