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)

Open
#1,258 0 comments 0 reactions 0 assignees View on GitHub
bug p2
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.