You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I searched existing issues and did not find a duplicate.
I included enough detail to reproduce or investigate the problem.
Area
apps/web
Steps to reproduce
This is the default first-run path for any new user who does not have Codex: on a fresh
install there is nothing to clean or configure — adding your first project and sending a
message is enough. On an existing install, simulate the fresh client state first:
osascript -e 'quit app "T3 Code (Alpha)"'
mv "$HOME/Library/Application Support/t3code/Local Storage""$HOME/Library/Application Support/t3code/Local Storage.bak"
open -a "T3 Code (Alpha)"
Then:
Cmd+K → "Add project" → enter a path T3 Code has never seen (e.g. /tmp/repro-codex-default) → "Create & Add".
In the new thread, type any message and send, without ever opening the model picker.
Reproduced on the desktop app v0.0.28 and on the web dev build at main (32e7844).
Expected behavior
The first project/thread defaults to a provider that is actually installed and enabled
(e.g. the one the user authenticated during setup), and a thread never gets pinned to a
provider that cannot start.
Actual behavior
Every project created through the command palette gets a hard-coded defaultModelSelection: { instanceId: "codex", ... }, and the first thread in it is
dispatched to codex. For a user without Codex this fails in one of two ways, depending on
settings:
codex not installed (fresh-install default, enabled defaults to true): ProviderAdapterProcessError: Failed to spawn Codex App Server process for command: codex app-server
codex disabled in settings: ProviderValidationError: Provider validation failed in ProviderService.startSession: Provider instance 'codex' is disabled in T3 Code settings.
Either way the thread is persisted with modelSelection: {"instanceId":"codex","model":"claude-fable-5"}
(codex instance, claude model — the composer keeps the model while pinning the wrong
instance) and every subsequent send fails the same way. The project keeps the codex
default, so future threads in it break too.
The bug then hides itself: once the user picks any provider in the composer, the draft
store's sticky selection (stickyActiveProvider) seeds all new drafts and wins over the
broken project default. So existing users only see mysteriously broken old threads they
cannot reproduce — while every genuinely new user without Codex walks straight into a
failed first message.
Root cause, from reading the code:
CommandPalette.tsx hard-codes codex as the defaultModelSelection.instanceId for
palette-created projects, regardless of provider state.
The composer's instance resolution in ChatComposer.tsx skips disabled instances when
scanning its candidates (draft pick → thread instance → project default), but when no
candidate matches it returns the persisted id verbatim instead of falling back to a
provider that can actually start. Selection also never checks installed/ready status,
so an enabled-but-not-installed codex is picked as if it were usable.
Impact
Major degradation or frequent failure
Version or commit
Desktop Alpha v0.0.28; also reproduced on main @ 32e7844 (dev build)
Environment
macOS (Darwin 25.4), T3 Code (Alpha) desktop + web dev build; Codex CLI not installed, Claude enabled/authenticated
Logs or stack traces
ProviderValidationError: Provider validation failed in ProviderService.startSession: Provider instance 'codex' is disabled in T3 Code settings.
at toValidationError (…/app.asar/apps/server/dist/bin.mjs:39745:9)
at startSession → ensureSessionForThread → processTurnStartRequested → processDomainEvent
ProviderAdapterProcessError: Provider adapter process error (codex) for thread …: Failed to spawn Codex App Server process for command: codex app-server
at CodexAdapter.ts:1432 → startSession → ensureSessionForThread → processTurnStartRequested
Screenshots, recordings, or supporting files
Screen.Recording.2026-07-18.at.11.28.41.mov
Workaround
In the affected thread (and in the project's settings), manually pick a model from a
working provider once — a successful send re-persists the corrected selection. After any
manual provider pick, new threads are shielded by the sticky selection.
Before submitting
Area
apps/web
Steps to reproduce
This is the default first-run path for any new user who does not have Codex: on a fresh
install there is nothing to clean or configure — adding your first project and sending a
message is enough. On an existing install, simulate the fresh client state first:
Then:
/tmp/repro-codex-default) → "Create & Add".To restore your previous state afterwards:
Reproduced on the desktop app v0.0.28 and on the web dev build at main (32e7844).
Expected behavior
The first project/thread defaults to a provider that is actually installed and enabled
(e.g. the one the user authenticated during setup), and a thread never gets pinned to a
provider that cannot start.
Actual behavior
Every project created through the command palette gets a hard-coded
defaultModelSelection: { instanceId: "codex", ... }, and the first thread in it isdispatched to codex. For a user without Codex this fails in one of two ways, depending on
settings:
enableddefaults to true):ProviderAdapterProcessError: Failed to spawn Codex App Server process for command: codex app-serverProviderValidationError: Provider validation failed in ProviderService.startSession: Provider instance 'codex' is disabled in T3 Code settings.Either way the thread is persisted with
modelSelection: {"instanceId":"codex","model":"claude-fable-5"}(codex instance, claude model — the composer keeps the model while pinning the wrong
instance) and every subsequent send fails the same way. The project keeps the codex
default, so future threads in it break too.
The bug then hides itself: once the user picks any provider in the composer, the draft
store's sticky selection (
stickyActiveProvider) seeds all new drafts and wins over thebroken project default. So existing users only see mysteriously broken old threads they
cannot reproduce — while every genuinely new user without Codex walks straight into a
failed first message.
Root cause, from reading the code:
CommandPalette.tsxhard-codescodexas thedefaultModelSelection.instanceIdforpalette-created projects, regardless of provider state.
ChatComposer.tsxskips disabled instances whenscanning its candidates (draft pick → thread instance → project default), but when no
candidate matches it returns the persisted id verbatim instead of falling back to a
provider that can actually start. Selection also never checks installed/ready status,
so an enabled-but-not-installed codex is picked as if it were usable.
Impact
Major degradation or frequent failure
Version or commit
Desktop Alpha v0.0.28; also reproduced on main @ 32e7844 (dev build)
Environment
macOS (Darwin 25.4), T3 Code (Alpha) desktop + web dev build; Codex CLI not installed, Claude enabled/authenticated
Logs or stack traces
Screenshots, recordings, or supporting files
Screen.Recording.2026-07-18.at.11.28.41.mov
Workaround
In the affected thread (and in the project's settings), manually pick a model from a
working provider once — a successful send re-persists the corrected selection. After any
manual provider pick, new threads are shielded by the sticky selection.