anthropics / anthropics/claude-code-action
Action ignores ANTHROPIC_DEFAULT_SONNET_MODEL for internal Agent SDK sub-calls (regression in v1.0.104 / claude-cli 2.1.118)
- Dominant language
- TypeScript
- Stars
- 8.9k
- Forks
- 2.1k
- Avg merge
- 3d 9h
- Merged PRs (30d)
- 10
Description
## Summary
`claude-code-action@v1` (>=v1.0.104, claude-cli 2.1.118) partially honours `ANTHROPIC_DEFAULT_SONNET_MODEL`:
- ✅ The **top-level** review conversation correctly uses the configured preset.
- ❌ **Internal Agent SDK sub-calls** (Task dispatch / planning step / sub-agent) ignore the override and send the literal `claude-sonnet-4-6` model name.
When the action is configured with `ANTHROPIC_BASE_URL=https://openrouter.ai/api` (an officially documented setup for routing through an LLM gateway), the proxy receives the literal Sonnet name and routes it to vertex/bedrock Sonnet, billing the proxy key. The user pays for Sonnet despite explicitly opting into a cheaper preset.
## Reproduction
1. In a repo, set:
- `ANTHROPIC_BASE_URL=https://openrouter.ai/api`
- `ANTHROPIC_DEFAULT_SONNET_MODEL=@preset/minimax-minimax-m2-7-no-thinking`
- `ANTHROPIC_DEFAULT_HAIKU_MODEL=@preset/minimax-minimax-m2-7-no-thinking`
- `OPENROUTER_API_KEY` secret with a paid OR account.
2. Wire `anthropic_api_key` to `${{ secrets.OPENROUTER_API_KEY }}`.
3. Run `anthropics/claude-code-action@v1` (>= v1.0.104) against any PR.
4. Inspect OpenRouter `/v1/activity` — observe `anthropic/claude-sonnet-4.6` requests on the OR key, despite the preset override.
## Expected behavior
All SDK calls (top-level + sub-calls) honour `ANTHROPIC_DEFAULT_SONNET_MODEL`. Zero `anthropic/claude-sonnet-*` requests should appear on the proxy account when the override points at a non-Anthropic preset.
## Actual behavior
Sub-calls send the literal `claude-sonnet-4-6` model name. Top-level final review still uses the preset (so the user-facing output looks correct), but the OR account silently accumulates Sonnet charges.
## Smoking-gun evidence
OpenRouter generation pulled by ID, fired during a reviewer run on a repo configured with the Minimax preset:
```json
{
"id": "gen-1777134452-vDJrQWnyZ2Yy0V8gXmOk",
"created_at": "2026-04-25T16:27:32.064Z",
"model": "anthropic/claude-4.6-sonnet-20260217",
"provider_name": "Google",
"user_agent": "claude-cli/2.1.119 (external, claude-code-github-action)",
"app": { "title": "Claude Code", "slug": "claude-code", "id": 2627404 },
"tokens_prompt": 19420,
"tokens_completion": 82,
"usage": 0.08345025,
"finish_reason": "tool_calls",
"session_id": "6b89d331-c5a7-42b9-9fe6-559f97b42b99"
}
```
Runner env at the same run start (16:27:32 was inside reviewer run `24935331336`, primary step):
```
ANTHROPIC_BASE_URL: https://openrouter.ai/api
ANTHROPIC_AUTH_TOKEN: ***
ANTHROPIC_DEFAULT_SONNET_MODEL: @preset/minimax-minimax-m2-7-no-thinking
ANTHROPIC_DEFAULT_HAIKU_MODEL: @preset/minimax-minimax-m2-7-no-thinking
```
The sub-call ignored the env override and sent the literal Sonnet name.
Independent confirmation on a second run: PR #339 reviewer run `24832459759` on 2026-04-23 11:32 UTC, log line `Download action repository 'anthropics/claude-code-action@v1' (SHA:b4d67413279fc18c6e5de930ae307c4f108714eb)`, was the first reviewer run after `b4d67413` (v1.0.104 / claude-cli 2.1.118) became the `@v1` HEAD — and the first day OpenRouter recorded Sonnet requests after a 7-day clean run.
## Regression range (`@v1` SHA history)
| Date (UTC) | Tag | SHA | claude-cli | Status |
|---|---|---|---|---|
| 2026-04-22 | v1.0.103 | `4e5d8b13` | 2.1.117 | clean |
| **2026-04-23 00:42** | **v1.0.104** | **`b4d67413`** | **2.1.118** | **first leak day — confirmed in run log** |
| 2026-04-23 23:24 | v1.0.105 | `e58dfa55` | 2.1.119 | leaks |
| 2026-04-25 | v1.0.106/107 | `2da6cfae` / `567fe954` | 2.1.120 / 2.1.119 | leaks |
Seven days on v1.0.99 → v1.0.103 (claude-cli 2.1.112 → 2.1.117) had **zero** Sonnet leak. Regression introduced in the 2.1.117 → 2.1.118 bump.
## Workaround
Pin to `anthropics/claude-code-action@4e5d8b13` (v1.0.103) until fixed.
## Impact
Users following the documented "Configure with a proxy or LLM gateway" pattern with a Minimax / non-Anthropic preset are silently billed by the proxy for Sonnet calls they did not request. On the affected repo this was USD ~$1.16 across two days of normal PR activity.
## Environment
- Action: `anthropics/claude-code-action@v1` (resolves to `567fe954a4527e81f132d87d1bdbcc94f7737434`)
- claude-cli: 2.1.119
- Agent SDK: 0.2.119
- Proxy: OpenRouter (`https://openrouter.ai/api`)
- Auth: `ANTHROPIC_AUTH_TOKEN` set to `OPENROUTER_API_KEY`
Contributor guide
Research direction
Start by comparing the action revisions 4e5d8b13, b4d67413, and 567fe954 around the claude-cli 2.1.117 to 2.1.118 upgrade, then trace how the action launches top-level and internal Agent SDK calls. Reproduce with the listed OpenRouter environment and inspect request activity. Done means every SDK call honors ANTHROPIC_DEFAULT_SONNET_MODEL and no literal Sonnet requests appear when a non-Anthropic preset is configured.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, typescript
- Domain
- ci-cd, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100