anthropics / anthropics/claude-code-action

shell-quote treats # in claude_args values as comments, causing null values and AJV crash

Abierto
#980 1 comentario 0 reacciones 0 asignados Ver en GitHub
bug dev-experience p2
Lenguaje dominante
TypeScript
Estrellas
8.9k
Forks
2.1k
Merge medio
3 d 9 h
PR fusionados (30 d)
10

Descripción

**Describe the bug**

The action uses `shell-quote`'s `parse()` to process `claude_args`. When a flag value contains `#` (even if backslash-escaped), `shell-quote` treats it as a comment and returns a `{comment: "..."}` object instead of a string. The action's `.filter(arg => typeof arg === 'string')` then drops it, leaving the flag with no value, which the parser sets to `null`. This `null` propagates into the SDK config and triggers an AJV schema validation crash before any API calls are made.

**To Reproduce**

1. Create a workflow using `anthropics/claude-code-action@v1`
2. Set `claude_args` with a value containing `#` (note: `#` is preserved inside YAML literal blocks `|`):
```yaml
claude_args: |
--model claude-sonnet-4-5-20250929
--append-system-prompt \#\ Use\ best\ practices
```
3. Run the workflow
4. The action crashes with an AJV validation error at $0 cost

You can verify the parsing behavior locally with Node.js:

```js
const { parse } = require('shell-quote');

// Backslash escaping collapses \# to #, which shell-quote treats as a comment
parse('--append-system-prompt \\#\\ Use\\ best\\ practices')
// → ["--append-system-prompt", {comment: " Use best practices"}]

// The action filters out non-string objects:
// → ["--append-system-prompt"]
// → parser sets: {"append-system-prompt": null}

// Unescaped # is also treated as a comment
parse('--append-system-prompt # Use best practices')
// → ["--append-system-prompt", {comment: " Use best practices"}]

// Double-quoted values work correctly
parse('--append-system-prompt "# Use best practices"')
// → ["--append-system-prompt", "# Use best practices"]
```

**Expected behavior**

The action should parse `#` in flag values as literal text, not as a comment. At minimum, `null` values should be rejected with a clear error instead of being passed to the SDK.

**Workflow yml file**

```yaml
name: Repro AJV Crash
on: workflow_dispatch

jobs:
repro:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: "Say hello"
claude_args: |
--model claude-sonnet-4-5-20250929
--append-system-prompt \#\ Use\ best\ practices
```

**API Provider**

[x] Anthropic First-Party API (default)
[ ] AWS Bedrock
[ ] GCP Vertex

**Additional context**

The root cause is in `base-action/src/parse-sdk-options.ts`, `parseClaudeArgsToExtraArgs()`:

```typescript
const args = parseShellArgs(claudeArgs).filter(
(arg): arg is string => typeof arg === "string", // drops {comment: "..."} objects
);
```

When the loop reaches a `--flag` whose value was dropped, `nextArg` is `undefined`, so the parser falls into the boolean flag branch and sets `result[flag] = null`. The resulting config:

```json
{
"model": "claude-sonnet-4-5-20250929",
"append-system-prompt": null
}
```

This `null` triggers the AJV crash:
```
SDK execution error: 14 | depsCount: ${X},
15 | deps: ${Y}}`};var Tj={keyword:"dependencies",type:"object",schemaType:"object",...
error: Claude Code process exited with code 1
```

**Workaround:** Double-quote values containing `#`:
```yaml
# BROKEN — backslash escaping still results in # after shell-quote parses it
claude_args: |
--append-system-prompt \#\ Use\ best\ practices

# WORKS — double quotes prevent # from being treated as a comment
claude_args: |
--append-system-prompt "# Use best practices"
```

May be related to #947, #892, #852 which report the same AJV error signature.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.