Thanks to visit codestin.com
Credit goes to github.com

Skip to content

bug: Inconsistent behavior when PATCHing a route's upstream.nodes: cannot change from hash table format back to array format #13045

@Ethan-Zhang-ZH

Description

@Ethan-Zhang-ZH

Current Behavior

Description:

When using the Admin API to PATCH a route's upstream.nodes field, there is an inconsistency in data type conversion. Currently, the nodes field can be updated from the array format to the hash table format successfully. However, once the nodes field is set to the hash table format, a subsequent PATCH request attempting to change it back to the array format fails, even though both formats are documented as valid in the Admin API.

Expected Behavior

Expected behavior:
Since both nodes formats are documented as valid in the Admin API, the PATCH operation should allow switching between them in both directions, as long as the payload is valid according to the schema.

Actual behavior:
Switching from array to hash table works, but switching from hash table back to array fails with a validation error. This indicates that the schema validator does not permit changing the type of the nodes field during a PATCH operation, despite both types being acceptable for the resource.

Additional context:
The issue likely stems from how PATCH handles partial updates: after the nodes field is stored as a hash table, the validator expects subsequent PATCH requests to also provide a hash table for that field, even though the overall schema allows either type. Because both formats are officially supported, the API should be able to handle type conversions in both directions.

Thank you for looking into this!

Error Logs

No response

Steps to Reproduce

Example formats:

  • Array format (node1):

    {
      "upstream": {
        "nodes": [
          {
            "weight": 1,
            "priority": 0,
            "host": "127.0.0.1",
            "port": 80
          }
        ]
      }
    }
  • Hash table format (node2):

    {
      "upstream": {
        "nodes": {
          "127.0.0.1:8080": 1
        }
      }
    }

Steps to reproduce:

  1. Create a route with the array format (node1) using a PUT request:

    curl -X PUT http://127.0.0.1:9180/apisix/admin/routes/test \
      -H "X-API-KEY: your-api-key" \
      -d '{
        "uri": "/anything",
        "upstream": {
          "nodes": [
            {
              "weight": 1,
              "priority": 0,
              "host": "127.0.0.1",
              "port": 80
            }
          ]
        }
      }'
  2. Change the route to the hash table format (node2) using a PATCH request:

    curl -X PATCH http://127.0.0.1:9180/apisix/admin/routes/test \
      -H "X-API-KEY: your-api-key" \
      -d '{
        "upstream": {
          "nodes": {
            "127.0.0.1:8080": 1
          }
        }
      }'

    → This succeeds.

  3. Now try to change it back to the array format (node1) using another PATCH request:

    curl -X PATCH http://127.0.0.1:9180/apisix/admin/routes/test \
      -H "X-API-KEY: your-api-key" \
      -d '{
        "upstream": {
          "nodes": [
            {
              "weight": 1,
              "priority": 0,
              "host": "127.0.0.1",
              "port": 80
            }
          ]
        }
      }'

    → This fails with the following error:

    {"error_msg":"invalid configuration: property \"upstream\" validation failed: property \"nodes\" validation failed: object matches none of the required"}
    

Environment

  • APISIX version (run apisix version):
  • Operating system (run uname -a):
  • OpenResty / Nginx version (run openresty -V or nginx -V):
  • etcd version, if relevant (run curl http://127.0.0.1:9090/v1/server_info):
  • APISIX Dashboard version, if relevant:
  • Plugin runner version, for issues related to plugin runners:
  • LuaRocks version, for installation issues (run luarocks --version):

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    🏗 In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions