Skip to content

fix(server): text generation falls back when the selected provider failed to load - #33748

Open
only21mil wants to merge 1 commit into
pingdotgg:mainfrom
only21mil:fix/text-generation-missing-snapshot-fallback
Open

only21mil wants to merge 1 commit into
pingdotgg:mainfrom
only21mil:fix/text-generation-missing-snapshot-fallback

Conversation

@only21mil

@only21mil only21mil commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Problem

When the provider chosen for text generation is configured but T3 could not load it, thread titles, branch names, commit messages and PR text fail even when another provider is ready. The title stays as the truncated first message, and the server logs Thread title generation failed … No provider instance registered for id 'codex'.

A provider fails to load when its secrets can't be read (for example, a 1Password reference while 1Password is signed out or locked), when its config doesn't decode, or when its driver fails to create the instance. Settings show it as "Disabled" with the reason. The settings layer keeps it as the text generation model because it is still enabled in config.

Change

TextGeneration.generate already switches to another ready provider when the selected one's probe failed (missing CLI or signed out, #29607) or its usage window is exhausted. A provider that failed to load has no live instance, so it has no snapshot, and the check skipped it: selected was undefined, unusable was false, and the request failed in resolveInstance.

A selection with no snapshot now counts as unusable and takes the same fallback. Unlike the pending case the existing comment protects, where a live instance may still succeed, a request with no instance is sure to fail. If no other provider qualifies, the original selection is kept and fails as before.

Scope and approval

This is a small, focused fix for an obvious bug, so it has no issue. The change is limited to the unusable condition.

Verification

Test: a new not registered row in the preflight table in CodexTextGeneration.test.ts fails on main (4c361199f4) with No provider instance registered for id 'codex' and passes with the fix. vp run check:changed upstream/main passes.

Each case ran on a fresh sandboxed dev server per side named "Test machine", with the web client in T3's Browser panel (all input was clicks and typing there), a new thread on Replay (dev) and Codex as the text generation model.

1. Secrets can't be read (head fb04ce5d5d, before on 4c361199f4). The real op 2.41.1 answers as signed out. The real claude 2.1.321, signed in through an API gateway, writes the title.

Settings: Codex is Disabled because the real 1Password CLI could not read OPENAI_API_KEY; the real Claude CLI is Authenticated

Before: the thread keeps the truncated first message as its title

After: the real Claude CLI generates the title

In cases 2 and 3 the fallback target is a scripted ACP agent set as the Grok CLI, so no account is needed (head fb04ce5d5d, before on main 0f13d2ccbd).

2. Config doesn't decode (Codex binaryPath: 42).

Settings on the head: Codex is Disabled with "Invalid config for instance 'codex'"; the scripted Grok agent is ready

Before (main): the title stays as the truncated first message

After (head): the scripted Grok agent writes the title

Matching lines from both server logs (Failed to (decode|create) provider instance|Thread title generation failed):

main.log:Failed to decode provider instance
main.log:Thread title generation failed
head.log:Failed to decode provider instance
Server log excerpts, main then head (local paths replaced, long lines cut)
# main 0f13d2ccbd, Codex config binaryPath: 42 (server log, paths redacted)
[04:16:22.310] ERROR (#2): Failed to decode provider instance config
  {
    instanceId: 'codex',
    driver: 'codex',
    detail: 'Expected string | undefined\n  at ["binaryPath"]'
  }
[04:17:17.146] WARN (#2715): Thread title generation failed
  {
    threadId: 'abec24e7-abbb-44fa-9d67-f4b88a842f7c',
    requestId: '91f75f92-e303-42c5-b23a-145edcd26015:initial-message',
    cause: "TextGenerationError: Text generation failed in generateThreadTitle: No provider instance registered for id 'codex'.\n" +
      '    at file://<main-worktree>/apps/server/src/textGeneration/TextGeneration.ts:64:13\n' +
      '    at ThreadTitleRegenerationService.execute (file://<main-worktree>/apps/server/src/orchestration-v2/EffectWorker.ts:543:16)\n' +
      '    at ThreadTitleRegenerationService.execute (definition) (file://<main-worktree>/apps/server/src/orchestration-v2/ThreadTitleRegenerationService.ts:110:80)\n' +
      '    at OrchestrationEffectExecutorV2.execute (file://<main-worktree>/apps/server/src/orchestration-v2/EffectWorker.ts:786:14)\n' +
# head fb04ce5d5d, Codex config binaryPath: 42 (server log, paths redacted)
[04:12:45.636] ERROR (#2): Failed to decode provider instance config
  {
    instanceId: 'codex',
    driver: 'codex',
    detail: 'Expected string | undefined\n  at ["binaryPath"]'
  }
# grep 'title generation failed|No provider instance' in the head log:
0
# scripted agent trace (fallback target):
{"at":"2026-11-11T04:14:58.485Z","pid":3928584,"event":"session.new","sessionId":"scripted-ad09d547-3a85-43f1-ab77-47028fc12b78"}
{"at":"2026-11-11T04:14:58.500Z","pid":3928584,"event":"prompt","sessionId":"scripted-ad09d547-3a85-43f1-ab77-47028fc12b78","reply":"{\"title\":\"Pricing page c

3. Driver fails to create the instance (Codex shadow home equal to its home, which the real Codex driver rejects).

Settings on the head: Codex is Disabled with "Driver 'codex' failed to create instance"

Before (main): the title stays as the truncated first message

After (head): the scripted Grok agent writes the title

Matching lines from both server logs:

head.log:Failed to create provider instance
main.log:Failed to create provider instance
main.log:Thread title generation failed
Server log excerpts, main then head (local paths replaced, long lines cut)
# main 0f13d2ccbd, Codex driver fails to start (shadow home = home) (server log, paths redacted)
[04:19:50.043] ERROR (#2): Failed to create provider instance
  {
    instanceId: 'codex',
    driver: 'codex',
    detail: "Codex shadow home path '/srv/codex-home' must be different from the shared home path '/srv/codex-home'."
  }
[04:20:44.092] WARN (#2535): Thread title generation failed
  {
    threadId: '3febfa37-b8fb-4510-b159-7e898c06bf6f',
    requestId: '4649390f-03b6-4a66-996b-fac352edb25d:initial-message',
    cause: "TextGenerationError: Text generation failed in generateThreadTitle: No provider instance registered for id 'codex'.\n" +
      '    at file://<main-worktree>/apps/server/src/textGeneration/TextGeneration.ts:64:13\n' +
# head fb04ce5d5d, Codex driver fails to start (shadow home = home) (server log, paths redacted)
[04:17:56.384] ERROR (#2): Failed to create provider instance
  {
    instanceId: 'codex',
    driver: 'codex',
    detail: "Codex shadow home path '/srv/codex-home' must be different from the shared home path '/srv/codex-home'."
  }
# grep 'title generation failed|No provider instance' in the head log:
0
# scripted agent trace (fallback target):
{"at":"2026-11-11T04:19:03.688Z","pid":3971711,"event":"session.new","sessionId":"scripted-ab0c2d87-bec1-4277-9bed-c524b3a08ee6"}
{"at":"2026-11-11T04:19:03.698Z","pid":3971711,"event":"prompt","sessionId":"scripted-ab0c2d87-bec1-4277-9bed-c524b3a08ee6","reply":"{\"title\":\"Pricing page c

Not checked:

  • 1Password locked behind its desktop app; Claude signed in with a claude.ai subscription.
  • Desktop and mobile. The title is generated on the server; I did not capture those clients.

A Codex binary that exits at start is a failed probe, not a failed load, so it is outside this fix.

Generated with Claude Opus 5.5 in T3 Code Nightly

…iled to load

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Nov 10, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at fb04ce5

Macroscope's review found this PR approvable — Text generation now uses its existing fallback when the selected provider failed to load. Existing provider eligibility checks and default model choices remain unchanged.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The fallback eligibility check now treats a missing provider snapshot as unusable. The preflight test covers the case where the primary provider is not registered.

Changes: Provider fallback selection

Layer / File(s) Summary
Fallback eligibility and preflight coverage
apps/server/src/textGeneration/TextGeneration.ts, apps/server/src/textGeneration/CodexTextGeneration.test.ts
The fallback check now includes a missing provider snapshot. The preflight test covers a primary provider that is not registered.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: juliusmarminge, maria-rcks

Merge Risk: Minimal · up to fb04c

Failed provider loads can fall back to a ready provider. No merge-blocking issue was identified.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title clearly summarizes the main change: text generation falls back when the selected provider fails to load.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The pull request description includes all required sections: Problem, Change, Scope and approval, and Verification. It explains the failure mode and expected behavior, describes the focused code chang…
Full details: Description check

Explanation

The pull request description includes all required sections: Problem, Change, Scope and approval, and Verification. It explains the failure mode and expected behavior, describes the focused code change, justifies the absence of a linked issue, reports automated and manual verification with observed results, and lists unverified scenarios. It also identifies the model and harness used.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 4c36119 and fb04ce5.

Files selected for processing: 2

  • apps/server/src/textGeneration/CodexTextGeneration.test.ts
  • apps/server/src/textGeneration/TextGeneration.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

This branch has not been deployed

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

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant