Skip to content

[Bug] PUT /api/subagent-models rejects bare native ids in pickerOrder, blocking the documented complete-picker ordering #6338

Closed

Description

@arikon

Client or integration

Direct HTTP/API client (management API of the bundled OpenCodex.app proxy); also affects the OpenCodex dashboard.

Area

Catalog / models

Summary

The complete-picker ordering feature is implemented in the catalog engine and documented, but the only supported write path rejects the input it requires.

modelPickerOrder supports ordering the complete picker when the array includes a bare native id (e.g. gpt-5.6-sol). This is implemented in applyFullModelPickerOrder (src/codex/catalog/build-entries.ts) and documented in docs-site/src/content/docs/guides/model-ordering.md ("To order the complete picker, include a bare native id", with a worked example modelPickerOrder: ["gpt-5.6-sol", "opencode-go/glm-5.3"]).

However, PUT /api/subagent-models validates every pickerOrder entry against visible routed slugs only and rejects bare native ids:

// src/server/management/agent-settings-routes.ts
const visible = new Set(filterCatalogVisibleModels(models, config).map(catalogModelSlug).filter(slug => slug.includes("/")));
if (pickerOrder.some(model => !visible.has(model))) {
  return jsonResponse({ error: "pickerOrder must contain each visible routed model at most once" }, 400);
}

tests/routing/subagent-roster-retention.test.ts pins { pickerOrder: ["gpt-5.5"] } as an invalid body, so the rejection appears intentional at the API layer. The dashboard follows suit: once a saved order contains a native id, the custom-order editor locks with the nativeLocked message and cannot edit or re-save it.

The result is a documented feature that cannot be created or edited through any supported path. Config hand-edits work (the engine honors them on the next catalog converge), but they bypass the API's ownership, staleness and rebase protections, and a running proxy must be restarted to pick the change up.

Expected: a bare id that names a visible native catalog row (present in nativeModelRows(config) / NATIVE_OPENAI_MODELS) is accepted for complete-picker ordering, matching the documented behavior and the engine implementation. Observed: 400 pickerOrder must contain each visible routed model at most once.

Reproduction

On opencodex 2.74.0 (bundled macOS app CLI) with any routed provider configured:

  1. Start the proxy (OpenCodex.app does this automatically).
  2. Send the documented complete-picker payload with a bare native id:
TOKEN=$(cat ~/.opencodex/admin-api-token)
PORT=$(jq -r .port ~/.opencodex/config.json)
curl -s -X PUT http://127.0.0.1:$PORT/api/subagent-models \
  -H "X-OpenCodex-API-Key: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"pickerOrder":["gpt-5.5"]}'
# -> {"error":"pickerOrder must contain each visible routed model at most once"}
  1. Send the same request with a routed-only list:
curl -s -X PUT http://127.0.0.1:$PORT/api/subagent-models \
  -H "X-OpenCodex-API-Key: $TOKEN" -H 'Content-Type: application/json' \
  -d '{"pickerOrder":["eliza-openrouter/z-ai-glm-5.3"]}'
# -> 200 ok

Routed-only lists are accepted; the bare native id required for complete ordering is the only rejected form. Validation matches current dev (6eec1265c lineage). Related history: #1649 introduced modelPickerOrder, #3774/#3801 added dashboard presets; both left native-id handling outstanding.

Version

2.74.0

Operating system

macOS (observed on the bundled OpenCodex.app CLI; the route is platform-independent)

Provider and model

Not provider-specific; observed with routed eliza-openrouter/z-ai-glm-5.3 and native gpt-5.5.

Logs or error output

{"error":"pickerOrder must contain each visible routed model at most once"}

Redacted configuration

{
  "port": 10100,
  "providers": {
    "eliza-openrouter": {
      "adapter": "openai-chat",
      "baseUrl": "https://example.internal/raw/openrouter/v1"
    }
  }
}

Activity

  1. added
    bugSomething isn't working
    catalogModel catalog, slugs, visibility, routed entries
    on Sep 30, 2026
  2. added a commit that references this issue on Oct 1, 2026
    09a86e1
  3. lidge-jun commented on Oct 1, 2026

    @lidge-jun
    Owner

    Fixed on dev by #6346: PUT /api/subagent-models now accepts enabled bare native ids in pickerOrder, so the documented complete-picker ordering can be saved through the API. The dashboard editor still locks native-containing orders (documented limitation). Thanks for the precise report!

  4. github-actions commented on Oct 1, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: English.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcatalogModel catalog, slugs, visibility, routed entries

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions