[Bug]: One-shot text generation (commit/PR/branch/title) ignores the provider's configured model and falls back to claude-haiku-4-5, which backend guardrails can block
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Environment
- T3 Code 0.0.42 (linux-x64 runtime at
~/.t3/runtime/versions/0.0.42) - Arch Linux (kernel 7.2.3-arch1-3)
- Provider:
claudeAgentinstance withbinaryPathpointing at a wrapper that runs the Claude CLI through OpenRouter (ANTHROPIC_BASE_URL=https://openrouter.ai/api), custom modelz-ai/glm-5.3-flash - OpenRouter workspace guardrails block Anthropic models (only the GLM model is allowed)
Steps to reproduce
- Use a
claudeAgentprovider whose backend refusesclaude-haiku-4-5(e.g. OpenRouter with workspace guardrails that exclude Anthropic models), with a working custom model configured for threads. - Leave
textGenerationModelSelectionunset (default settings). - Press Commit on any repo with staged changes.
I captured the exact spawn t3 issues (via a logging wrapper around the configured binary):
claude-ori -p --output-format json \
--json-schema {"type":"object","properties":{"subject":{"type":"string"},"body":{"type":"string"},"branch":{"type":"string"}},...} \
--model claude-haiku-4-5 \
--settings {"disableAllHooks":true} --tools '' --disable-slash-commands \
--strict-mcp-config --permission-mode dontAsk
→ exit 1. stdout contains the real failure:
{"api_error_status":400, "is_error":true, "result":"API Error: 400 0 endpoints out of 4 requested are available matching your guardrail restrictions and data policy. … Model blocked by guardrail: 4 endpoints excluded", ...}
stderr contains only an informational line from our credential wrapper ("Using the OpenRouter credential from the global credential ~/.ori/credentials.json.").
Expected behavior
Commit-message generation should use a model that is actually configured/available on the provider instance — e.g. the instance's defaultModelSelection / custom model — instead of a hardcoded fallback slug that the backend may refuse.
Actual behavior
Every one-shot text-generation operation fails: the Commit button shows
Text generation failed in generateCommitMessage: Claude CLI command failed: Using the OpenRouter credential from the global credential ~/.ori/credentials.json.
i.e. the stderr of the spawn (the wrapper's informational notice) is shown as the entire error, while the real API error sits in stdout and is discarded. Thread-title generation fails the same way (I observed ~36 failing title spawns over several hours, 0 successes) and generateBranchName / generatePrContent share the same path.
Root cause in the 0.0.42 bundle: with settings.textGenerationModelSelection unset, resolveTextGenerationProvider() → fallbackTextGenerationProvider() selects DEFAULT_TEXT_GENERATION_MODEL_BY_PROVIDER[claudeAgent] = "claude-haiku-4-5", ignoring the instance's configured default/custom model. A secondary problem is that runClaudeJson reports stderr when non-empty on non-zero exit, so any wrapper's stderr chatter masks the actual API error from stdout.
Workaround
Setting textGenerationModelSelection explicitly in ~/.t3/userdata/settings.json fixes it immediately (picked up live, no restart needed):
"textGenerationModelSelection": { "instanceId": "claudeAgent", "model": "z-ai/glm-5.3-flash" }
Suggested fixes
- When
textGenerationModelSelectionis unset, fall back to the enabled provider instance's configured default model (e.g.defaultModelSelection/custom model) rather than a hardcoded slug; at minimum, skip fallback slugs that don't resolve in the instance's model catalog. - When the spawned CLI exits non-zero, include the stdout API error (or at least
api_error_status/resultfrom the JSON) in the surfaced error instead of preferring stderr, which may only contain wrapper notices.
Impact
Major degradation or frequent failure
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/server by tracing resolveTextGenerationProvider() and fallbackTextGenerationProvider(), then inspect runClaudeJson for non-zero exit handling. Verify that unset textGenerationModelSelection uses the enabled provider instance's configured model and that surfaced failures include the stdout API error rather than wrapper-only stderr; check commit, title, branch, and PR generation paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 65/100