Skip to content

fix(providers): lazily load chatgpt-web-codex admin helpers in PUT /api/providers/[id] - #13071

Merged
diegosouzapw merged 2 commits into
diegosouzapw:release/v3.8.51from
hartmark:fix/providers-put-lazy-chatgpt-web-codex-import
Sep 16, 2026
Merged

diegosouzapw merged 2 commits into
diegosouzapw:release/v3.8.51from
hartmark:fix/providers-put-lazy-chatgpt-web-codex-import

Conversation

@hartmark

@hartmark hartmark commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

PUT /api/providers/{id} -- renaming a connection, rotating its API key,
etc. -- for any provider returned a 500 after 17-50 seconds:

Error: Missing tiktoken_bg.wasm
    at module evaluation (open-sse/vendor/codex-chatgpt-web/lib/token-estimate.ts:2:1)

Live repro: PUT-ing a rename on a plain llama-cpp (openai-compatible)
connection -- nothing to do with chatgpt-web-codex at all.

Root Cause

#12355 already fixed this exact bug class in the sibling collection
route (src/app/api/providers/route.ts): a static top-level import of
chatgptWebCodexAdmin.ts evaluates that module's transitive chain (the
vendor ChatGPT-Web browser adapter -> token-estimate.ts -> tiktoken's WASM
tokenizer) on every request to the route, regardless of which provider is
actually being managed. That chain fails to bundle under Turbopack dev mode
even with tiktoken listed in serverExternalPackages (the standalone Node
require works fine; only Turbopack's bundling of this specific import
graph doesn't).

#12355 only touched the collection route and missed the identical
pattern
in the by-id route (src/app/api/providers/[id]/route.ts),
which has the same static import used only inside one
provider === "chatgpt-web-codex" branch of the PUT handler. #12355 also
shipped with no regression test, which is exactly how this sibling instance
went unnoticed for a week.

Fix

Same pattern as #12355: move the import into a lazy await import(...)
inside the one branch that actually needs it.

What This Deliberately Does NOT Change

src/app/api/providers/[id]/chatgpt-web-codex-doctor/route.ts keeps its
static import -- every request to that route already is for a
chatgpt-web-codex connection (it's in the route's own URL), so there's no
"unrelated provider pays the cost" problem there.

Evidence

New regression test source-inspects both general provider routes to assert
neither statically imports chatgptWebCodexAdmin.ts, and confirms the
doctor route's static import is intentionally left alone. Matches the
existing tests/unit/instrumentation-import-graph-12074.test.ts pattern for
import-graph invariants that can't be exercised by actually bundling under
Turbopack from this harness. Confirmed it fails against the pre-fix
[id]/route.ts and passes after the fix.

$ node --test tests/unit/providers-chatgpt-web-codex-lazy-import-12355.test.ts
tests 3, pass 3, fail 0

$ node --test tests/unit/providers-route-patch-method.test.ts tests/unit/codex-connection-edit-6562.test.ts \
    tests/unit/chatgpt-web-management-retirement.test.ts tests/unit/provider-patch-ratelimit-protection-11278.test.ts
tests 11, pass 11, fail 0
  • eslint on both touched files: clean

Live-verified against the exact failing request (deployed to my own dev
instance before opening this PR, given it was actively blocking a user):

Before: PUT /api/providers/{id} -> 500 in 17-50s, "Missing tiktoken_bg.wasm"
After:  PUT /api/providers/{id} -> 200 in 0.83s

@hartmark
hartmark marked this pull request as ready for review September 8, 2026 20:07
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 8, 2026
…codex admin helpers in PUT /api/providers/[id]) into dev/omniroute-dev-combined
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 9, 2026
…codex admin helpers in PUT /api/providers/[id]) into dev/omniroute-dev-combined
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 11, 2026
…codex admin helpers in PUT /api/providers/[id]) into dev/omniroute-dev-combined
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 11, 2026
…codex admin helpers in PUT /api/providers/[id]) into dev/omniroute-dev-combined
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 13, 2026
…codex admin helpers in PUT /api/providers/[id]) into dev/omniroute-dev-combined
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 13, 2026
…codex admin helpers in PUT /api/providers/[id]) into dev/omniroute-dev-combined
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 14, 2026
…codex admin helpers in PUT /api/providers/[id]) into dev/omniroute-dev-combined
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 14, 2026
…codex admin helpers in PUT /api/providers/[id]) into dev/omniroute-dev-combined
@diegosouzapw

Copy link
Copy Markdown
Owner

Clean, well-scoped fix — mirrors #12355's exact pattern for the sibling route, and the
source-inspection test is a smart way to pin an import-graph invariant that Turbopack bundling
can't be exercised for from the test harness. Please add a changelog fragment under
changelog.d/fixes/ before merge; the CI unit-test shard failures look like known base-red
noise but worth a clean local re-run to be sure.

hartmark and others added 2 commits September 15, 2026 16:03
…pi/providers/[id]

diegosouzapw#12355 fixed a static top-level import of chatgptWebCodexAdmin.ts in
src/app/api/providers/route.ts (the collection route): that module's
transitive chain (the vendor ChatGPT-Web browser adapter ->
token-estimate.ts -> tiktoken's WASM tokenizer) fails to bundle under
Turbopack dev mode even with tiktoken listed in serverExternalPackages
(the standalone Node require works fine; only Turbopack's bundling of
this specific import graph doesn't). A static import evaluated that whole
chain on every request regardless of provider, turning an unrelated
provider's bundling bug into a route-wide 500 for everyone.

diegosouzapw#12355 only touched the collection route and missed the identical pattern
in the by-id route (PUT /api/providers/[id]) -- observed live: renaming a
plain openai-compatible connection's name failed with "Missing
tiktoken_bg.wasm" after 17-50s, having never touched chatgpt-web-codex at
all. diegosouzapw#12355 also shipped with no regression test, which is exactly how
this sibling instance went unnoticed for a week.

Fix: same pattern as diegosouzapw#12355 -- move the import into a lazy
`await import(...)` inside the one `provider === "chatgpt-web-codex"`
branch that actually needs it.

New regression test (tests/unit/providers-chatgpt-web-codex-lazy-import-12355.test.ts)
source-inspects both general provider routes (route.ts and [id]/route.ts)
to assert neither statically imports chatgptWebCodexAdmin.ts, and confirms
the one legitimately-static import (the chatgpt-web-codex-only "doctor"
diagnostic route, where every request already is that provider) is left
alone. Matches the existing tests/unit/instrumentation-import-graph-12074.test.ts
pattern for import-graph invariants that can't be exercised by actually
bundling under Turbopack from this harness. Confirmed it fails against the
pre-fix route.ts (static import present) and passes after the fix.

Evidence:
- node --test tests/unit/providers-chatgpt-web-codex-lazy-import-12355.test.ts: 3/3 pass
- node --test tests/unit/providers-route-patch-method.test.ts tests/unit/codex-connection-edit-6562.test.ts
  tests/unit/chatgpt-web-management-retirement.test.ts tests/unit/provider-patch-ratelimit-protection-11278.test.ts:
  11/11 pass (unaffected)
- eslint on both touched files: clean
- Live-verified against the exact failing request: PUT /api/providers/{id}
  renaming a llama-cpp connection, previously 500 after 17-50s with
  "Missing tiktoken_bg.wasm", now 200 in 0.83s.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@hartmark
hartmark force-pushed the fix/providers-put-lazy-chatgpt-web-codex-import branch from 747a6d6 to ff54221 Compare September 15, 2026 14:14
@hartmark

Copy link
Copy Markdown
Contributor Author

Checked, and it's actually branch staleness rather than pure base-red: this branch was 217 commits behind release/v3.8.51. Re-running the exact CI-failing tests locally at the old head reproduced 25/39 failures; after rebasing (clean, no conflicts) that dropped to 2. Both remaining ones (dashboard-request-failed-redaction.test.ts, models-catalog-route.test.ts) I confirmed also fail on a completely clean release/v3.8.51 checkout with none of this PR's changes — genuine current base-red, unrelated to this fix (which only ever touched providers/[id]/route.ts and its own new test, 3/3 passing). Rebased, re-ran typecheck (clean) and the PR's own test suite, force-pushed. Added the changelog fragment — verified with check:changelog-integrity. Ready to merge from my side.

hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 15, 2026
…codex admin helpers in PUT /api/providers/[id]) into dev/omniroute-dev-combined
hartmark added a commit to hartmark/OmniRoute that referenced this pull request Sep 15, 2026
…codex admin helpers in PUT /api/providers/[id]) into dev/omniroute-dev-combined
@diegosouzapw
diegosouzapw merged commit 4591476 into diegosouzapw:release/v3.8.51 Sep 16, 2026
11 of 16 checks passed
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…pi/providers/[id] (diegosouzapw#13071)

Merged. Loading the chatgpt-web-codex admin helpers lazily keeps a rarely used path off `PUT /api/providers/[id]`'s cost — the kind of change that only shows up as latency nobody can explain.

Validated as a combined board first (this PR merged with the 21 siblings of the same wave on the release tip): eslint with the frozen suppressions, typecheck:core, check:open-sse-typecheck, complexity, cognitive-complexity, changelog-integrity, i18n new-key coverage, docs-counts, docs-sync, migration-numbering, provider-consistency and a duplicate-identifier audit all green, plus 176 passing / 0 failing focused node:test cases across the 25 test files the wave touches and the dashboard test under Vitest (2/0). Then re-validated alone on the fresh tip before this merge: conflicts re-resolved, file sizes rebaselined for this PR's own growth, eslint and this PR's focused tests re-run.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants