Summary
Two behaviors combine into a silent breakage for international Alibaba Token Plan users:
- The provider migration (shipped around 2026-07-21, created
config.json.bak-before-alibaba-provider-rename-*) renamed/merged user providers into the id alibaba-token-plan and deleted the user's duplicate (alibaba-token-plan-1).
- The router (
src/router.ts:158-162) ignores the user's saved baseUrl whenever the registry entry lacks allowBaseUrlOverride — and alibaba-token-plan (Beijing) lacks it, while alibaba-token-plan-intl (Singapore) has it.
Net effect: after the migration, config.json points at the saved international URL (token-plan.ap-southeast-1.maas.aliyuncs.com), but the router forces the Beijing URL (token-plan.cn-beijing.maas.aliyuncs.com). The international plan key is rejected there → every request fails with 401, with no warning that the configured baseUrl was discarded.
Registry asymmetry (src/providers/registry.ts)
| id |
baseUrl |
allowBaseUrlOverride |
alibaba-token-plan |
token-plan.cn-beijing... |
❌ (absent) |
alibaba-token-plan-intl |
token-plan.ap-southeast-1... |
✅ + baseUrlChoices |
Before/after migration (actual ~/.opencodex/config.json)
Before:
"alibaba-token-plan": { "baseUrl": "https://coding-intl.dashscope.aliyuncs.com/v1" },
"alibaba-token-plan-1": { "baseUrl": "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1" }
After:
"alibaba-token-plan": { "baseUrl": "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1" }
The saved URL survived, but router.ts resolves it back to Beijing at runtime.
Suggested fixes
- Honor the saved baseUrl: give
alibaba-token-plan allowBaseUrlOverride: true + baseUrlChoices (Beijing/Singapore), mirroring the -intl entry — or make region a first-class field.
- Fail loudly: when the router discards a user-configured
baseUrl because override isn't allowed, emit a warning. Silent ignoring is the footgun.
- Migrations must not rename user provider ids into a registry id with different semantics (region, override policy). If consolidation is needed, preserve the resolved baseUrl or map to the id matching the saved URL's region.
Workaround (confirmed)
Rename the provider id to alibaba-token-plan-intl in config.json and re-prefix disabledModels/providerContextCaps. The international URL is then honored; the endpoint returns 200.
Environment
opencodex 2.7.40 (npm global), macOS arm64. Note: ocx update runs migrations unattended via the background service, so this class of breakage lands without user interaction.
Summary
Two behaviors combine into a silent breakage for international Alibaba Token Plan users:
config.json.bak-before-alibaba-provider-rename-*) renamed/merged user providers into the idalibaba-token-planand deleted the user's duplicate (alibaba-token-plan-1).src/router.ts:158-162) ignores the user's savedbaseUrlwhenever the registry entry lacksallowBaseUrlOverride— andalibaba-token-plan(Beijing) lacks it, whilealibaba-token-plan-intl(Singapore) has it.Net effect: after the migration,
config.jsonpoints at the saved international URL (token-plan.ap-southeast-1.maas.aliyuncs.com), but the router forces the Beijing URL (token-plan.cn-beijing.maas.aliyuncs.com). The international plan key is rejected there → every request fails with 401, with no warning that the configured baseUrl was discarded.Registry asymmetry (
src/providers/registry.ts)allowBaseUrlOverridealibaba-token-plantoken-plan.cn-beijing...alibaba-token-plan-intltoken-plan.ap-southeast-1...baseUrlChoicesBefore/after migration (actual
~/.opencodex/config.json)Before:
After:
The saved URL survived, but
router.tsresolves it back to Beijing at runtime.Suggested fixes
alibaba-token-planallowBaseUrlOverride: true+baseUrlChoices(Beijing/Singapore), mirroring the-intlentry — or make region a first-class field.baseUrlbecause override isn't allowed, emit a warning. Silent ignoring is the footgun.Workaround (confirmed)
Rename the provider id to
alibaba-token-plan-intlinconfig.jsonand re-prefixdisabledModels/providerContextCaps. The international URL is then honored; the endpoint returns 200.Environment
opencodex 2.7.40 (npm global), macOS arm64. Note:
ocx updateruns migrations unattended via the background service, so this class of breakage lands without user interaction.