Skip to content

PUT /config/router repeatedly prefixes canonical backend_ref names #2729

Description

@duchangyong

Summary

PUT /config/router is not idempotent when it receives the canonical document returned by GET /config/router.

The Dashboard configuration path does not show this behavior: it reads and writes CanonicalConfig directly through /api/router/config/all and /api/router/config/update. The management API instead parses the submitted canonical document and exports it again through CanonicalConfigFromRouterConfig, which prefixes canonical backend reference names a second time.

Reproduction

Start with a valid v0.3 provider model whose canonical backend reference is:

providers:
  models:
    - name: test-model
      backend_refs:
        - name: test-model_primary
          endpoint: localhost:8000
          protocol: http
  1. Read the active document with GET /config/router.
  2. Submit that response unchanged with PUT /config/router.
  3. Read the document again.

Actual result

The backend reference name becomes:

name: test-model_test-model_primary

Repeating the same round trip adds another prefix.

Expected result

Submitting the canonical document returned by GET /config/router should not change it.

Root cause

canonicalEndpointName always returns modelName + "_" + backendRef.Name, even when backendRef.Name already starts with the generated model prefix. The management update path invokes CanonicalConfigFromRouterConfig after parsing the submitted document.

The latent prefix behavior was introduced by #1553, and the management update normalization path was introduced by #1660. The issue is present in v0.3.0 and current main.

Impact

  • External control planes cannot safely perform read-modify-write updates.
  • Configuration drift checks report false mismatches.
  • Rollback code that republishes a previously read document can mutate it again.
  • Repeated retries can keep extending backend reference names.

Proposed fix

Make canonical endpoint-name generation idempotent when the backend reference already contains the model prefix, and add regression coverage for:

  • canonical export of an already-canonical backend reference;
  • an unchanged GET /config/routerPUT /config/router round trip;
  • repeated round trips remaining stable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    In progress

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions