Skip to content

bug: Task execution ignores terminal model override, fails on subscription-incompatible default model #81

@vybe

Description

@vybe

Summary

When an agent's ~/.claude/settings.json contains a model not available on the assigned subscription (e.g. claude-3-5-haiku-latest on a Claude Max subscription), task execution via chat and paid endpoints fails with a misleading "Subscription token may be expired or revoked" error. However, terminal/WebSocket sessions work fine because they pass a model=sonnet query parameter that overrides the agent's default. This creates a confusing situation where manual chat works but programmatic/paid requests always fail.

Component

Backend / Task Execution Service + Agent Runtime

Priority

P1

Error

[TaskExecService] Failed to execute task on [agent]: Task execution failed (exit code 1): Subscription token may be expired or revoked. Generate a new one with 'claude setup-token'.

The actual cause is not an expired token — it's that the model (claude-3-5-haiku-latest) is not accessible with the subscription type (Claude Max). The error message from Claude Code is misleading.

Root Cause

Two separate issues combine:

  1. No model override in task execution: Terminal WebSocket connections pass model=sonnet as a URL parameter, but task_execution_service.execute_task() runs claude --print without specifying a --model flag. It relies on the agent's ~/.claude/settings.json, which may contain an incompatible model.

  2. Misleading error message: When Claude Code can't use a model due to subscription restrictions, it reports "Subscription token may be expired or revoked" instead of "Model not available on your subscription." This makes debugging much harder.

Reproduction Steps

  1. Create an agent and assign a Claude Max subscription
  2. Set the agent's ~/.claude/settings.json to {"model": "claude-3-5-haiku-latest"}
  3. Open a terminal session with model=sonnet → works fine
  4. Send a chat message via /api/agents/{name}/chat or /api/paid/{name}/chat → fails with "token expired" error
  5. The same agent, same token, same container — different result depending on the code path

Suggested Fix

Option A: Pass model to task execution (recommended)

The task execution service should accept and pass a --model parameter to claude --print. This could come from:

  • The chat/paid request body (already has model field in some endpoints)
  • The agent's DB config (a default_model column)
  • A fallback default like sonnet
# In task_execution_service.py, when building the claude command:
cmd = ["claude", "--print", message]
if model:
    cmd.extend(["--model", model])

Option B: Validate model compatibility on subscription assignment

When assigning a subscription, check if the agent's settings.json model is compatible. If not, warn or auto-update to a compatible default.

Option C: Improve error message (separate issue)

Claude Code should distinguish between "token expired" and "model not available on subscription" to make debugging easier.

Environment

  • Trinity version: f1dfd7d

Related

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions