Skip to content

[Bug]: Integrations page 500s when the catalog contains kimi/k3[1m] — Qoder managed-selector throw escapes the collection read #7512

Closed

Description

@mustardwheat

Client or integration

OpenCodex dashboard

Area

Dashboard

Summary

Opening the dashboard Integrations page (/#integrations) shows the red "Could not load integration state." notice, and every file-integration card stays in its placeholder state. The cause is server-side: GET /api/client-integrations returns HTTP 500 for the whole collection whenever the routed catalog contains a model whose ID holds a character the managed-selector grammar reserves (, or ]).

This is currently guaranteed to happen for any user signed into the Kimi coding subscription, because opencodex itself seeds kimi/k3[1m] into the catalog (src/providers/registry/model-seeds.ts, KIMI_CODING_K3_MODELS = ["k3", "k3[1m]", "k3-256k"]; the [1m] suffix is a local alias for the 1M context tier that is stripped before upstream requests). No user action involving Qoder is required: the client does not need to be installed, applied, or ever opened.

Expected: one client's inability to address a catalog row degrades to that client's own status (e.g. unsafe), and the collection read keeps answering 200 — the same isolation the route already applies to aside, and the same fail-closed classification readIntegrationState already returns for ClientPathError.

Reproduction

  1. Sign in a Kimi coding account (OAuth) so the catalog contains kimi/k3[1m] (visible, not disabled).
  2. Start the proxy and open the dashboard Integrations page, or run:
curl -H "X-OpenCodex-API-Key: $ADMIN_TOKEN" http://localhost:10100/api/client-integrations
  1. Observe:
{"error":"Qoder model ID cannot be represented by a managed array selector.","code":"integration_internal_error"}

GET /api/client-integrations/qoder alone reproduces the same 500; other single-client endpoints (e.g. /api/client-integrations/opencode) answer 200.

Root cause, on current dev (2.91.0):

  1. The collection route src/server/management/integration-routes.ts (GET /api/client-integrations) maps every client through readIntegrationState, but only wraps aside in a per-client try/catch.
  2. readIntegrationState (src/integrations/state.ts) unconditionally builds the desired contribution via buildIntegrationContribution — even when the client has no config file on disk (loadTarget returns ok for a missing file).
  3. buildQoderContribution (src/clients/config-export/qoder.ts) formats one [v2:provider=…,model=…] selector per customModels row and throws when formatSelectorConjunction returns null (src/integrations/merge.ts rejects values containing , or ], which the v2 grammar reserves). kimi/k3[1m] contains ].
  4. The throw escapes to the route's outer catch and becomes integration_internal_error (500), so the entire page fails because of one uninstalled client.

Notably, state.ts already documents this exact failure mode above its path-resolution guard ("The LIST route asks every client for its state, so letting that escape would answer 500 for the whole Integrations page"), but the guard only covers ClientPathError — the contribution build is unguarded. Sibling exporters handle the same situation gracefully: Droid omits unaddressable rows (config-export/droid.ts, if (!selector) continue) and ZCode ships the row without its model rule (config-export/zcode-store.ts); only Qoder throws. The throw is pinned by a test (tests/clients/qoder-client.test.ts, "refuses ambiguous model selectors instead of owning another provider's entry"), which makes sense for mutations — but the same builder is reused by the read-only status path.

Suggested direction (either works; we verified the first locally):

  • Keep the throw on write paths, but contain it on the status path: give the failure a dedicated error type (e.g. UnrepresentableSelectorError next to AmbiguousSelectorError in merge.ts), have Qoder throw it, and catch exactly that in readIntegrationState, classifying the client unsafe/unresolvable-path (the same fail-closed answer as the existing Droid "nonempty catalog yields zero fragments" case). Mutations and previews still refuse loudly.
  • Alternatively isolate every client in the collection route the way aside is isolated today.
  • Longer term, Qoder could follow the Droid convention and omit unaddressable rows from both the export document and the managed fragments.

Version

2.90.0 (pnpm global @bitkyc08/[email protected]); also reproduced on dev @ a4f335c (2.91.0)

Operating system

Windows 11 (build 26300)

Provider and model

kimi / k3[1m]

Logs or error output

$ curl -i -H "X-OpenCodex-API-Key: $ADMIN_TOKEN" http://localhost:10100/api/client-integrations
HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{"error":"Qoder model ID cannot be represented by a managed array selector.","code":"integration_internal_error"}

Screenshots and supporting files

Dashboard Integrations page shows a red notice banner: "无法加载集成状态。" (zh locale for "Could not load integration state.") while the other data surfaces (quota header, per-client cards fed by their own endpoints) load normally.

Redacted configuration

Relevant /api/models row (operator display-name override only; the ID itself comes from the built-in Kimi coding seed list):

{
  "id": "k3[1m]",
  "provider": "kimi",
  "namespaced": "kimi/k3[1m]",
  "disabled": false,
  "contextWindow": 1048576
}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

  1. github-actions commented on Oct 22, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: English.

  2. added
    bugSomething isn't working
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    catalogModel catalog, slugs, visibility, routed entries
    guiDashboard, tray, settings UI
    on Oct 22, 2026
  3. Ingwannu commented on Oct 22, 2026

    @Ingwannu
    Owner

    Confirmed on current dev bf4eb1209672 with actual loopback HTTP requests: the pre-fix regression returns 500 for both k3[1m] and comma-containing model IDs, and the same construction exception also breaks the collection with an installed Qoder target.

    Draft fix #7519, commit 13ab9d58e6, catches only the dedicated selector-construction refusal in the shared status reader. Qoder becomes unsafe / unresolvable-path; sibling statuses remain visible. Preview/mutations continue refusing, exact ownership grammar is unchanged, matching target metadata is retained, and target/store contents remain unchanged on the refusal paths.

    Final focused/adjacent validation: 173 passed / 0 failed, including five new HTTP/error-propagation cases and layout/structure/size gates. Privacy and whitespace checks passed. Local typecheck and the final Pagefind docs-build hook each reached the 300-second cap, so neither is claimed complete; the PR stays Draft pending hosted validation and independent review. No live client/provider/configuration was changed, and this issue remains open until verified integration.

  4. lidge-jun commented on Oct 24, 2026

    @lidge-jun
    Owner

    Fixed on dev by #7545 (5253164), which carries #7519 by @Ingwannu. A catalog model whose ID contains a reserved selector character (such as kimi/k3[1m]) now marks only that client as unsafe / unresolvable-path, so GET /api/client-integrations no longer returns 500 for the whole collection. This ships in the next release after 2.92.0; please reopen if it recurs.

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

    account-poolOAuth, credentials, Codex pool, quota, failover, plansbugSomething isn't workingcatalogModel catalog, slugs, visibility, routed entriesguiDashboard, tray, settings UI

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions