claude-code - 💡(How to fix) Fix [BUG] Agent SDK query() does not expand slash commands / skills — passed as literal prompt text [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#46377Fetched 2026-04-11 06:21:53
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
0
Author
Timeline (top)
labeled ×4commented ×1cross-referenced ×1

When using the Agent SDK's query() API with a prompt that starts with a slash command (e.g., /ask ... or /jira ...), the slash command is not expanded into the skill's content. Instead, the literal string is passed through as the user prompt. This contrasts with the interactive CLI, where typing /ask auto-expands the skill content before the model sees it.

Root Cause

Since the SDK spawns the Claude CLI as a subprocess (pathToClaudeCodeExecutable), the CLI has all the machinery to expand slash commands — it discovers them, lists them in init, and makes the Skill tool available. The expansion logic just doesn't run for prompts provided via the SDK's query() parameter. It appears the CLI only expands slash commands in the interactive TUI input path, not in the non-interactive/SDK prompt path.

This creates a meaningful gap: skills that work reliably in the interactive CLI (via auto-expansion) become unreliable when used programmatically through the SDK (dependent on model choosing to call the Skill tool).

Code Example

import { query } from '@anthropic-ai/claude-agent-sdk';
   
   const q = query({
     prompt: '/ask What does this function do?',
     options: {
       cwd: '/path/to/project',
       settingSources: ['user', 'project'],
       pathToClaudeCodeExecutable: '/usr/local/bin/claude',
     },
   });

---

{
  "type": "system",
  "subtype": "init",
  "slash_commands": ["ask", "jira", "push", ...],
  "skills": ["ask", "jira", "push", ...],
  "tools": ["Skill", ...]
}
RAW_BUFFERClick to expand / collapse

Description

When using the Agent SDK's query() API with a prompt that starts with a slash command (e.g., /ask ... or /jira ...), the slash command is not expanded into the skill's content. Instead, the literal string is passed through as the user prompt. This contrasts with the interactive CLI, where typing /ask auto-expands the skill content before the model sees it.

Steps to Reproduce

  1. Create a skill in .claude/skills/ask/SKILL.md (or any other skill)
  2. Use the Agent SDK to start a session:
    import { query } from '@anthropic-ai/claude-agent-sdk';
    
    const q = query({
      prompt: '/ask What does this function do?',
      options: {
        cwd: '/path/to/project',
        settingSources: ['user', 'project'],
        pathToClaudeCodeExecutable: '/usr/local/bin/claude',
      },
    });
  3. Observe the session events

Expected Behavior

The /ask prefix should be recognized as a slash command, expanded into the skill's rendered SKILL.md content (just like the CLI does), and the expanded content should be what the model receives.

Actual Behavior

  • The init event correctly discovers the skill and lists it in both skills and slash_commands arrays
  • The Skill tool is available in the tools list
  • But the prompt /ask What does this function do? is passed through as literal text — the model receives the raw string
  • The model may or may not call the Skill tool itself to load the skill (unreliable — it often just starts working on the literal text)

Evidence from Logs

The init event shows the CLI subprocess knows about the skill:

{
  "type": "system",
  "subtype": "init",
  "slash_commands": ["ask", "jira", "push", ...],
  "skills": ["ask", "jira", "push", ...],
  "tools": ["Skill", ...]
}

But the model's first response goes straight to tool calls (Bash, Agent, etc.) without ever invoking Skill({ skill: "ask" }). In a ~7800-line session, the Skill tool was only called once (for a different skill, push), and never for the slash command in the original prompt.

Environment

  • Claude Code version: 2.1.100
  • Agent SDK: @anthropic-ai/claude-agent-sdk
  • OS: Linux (Debian)
  • Node.js subprocess via pathToClaudeCodeExecutable

Analysis

Since the SDK spawns the Claude CLI as a subprocess (pathToClaudeCodeExecutable), the CLI has all the machinery to expand slash commands — it discovers them, lists them in init, and makes the Skill tool available. The expansion logic just doesn't run for prompts provided via the SDK's query() parameter. It appears the CLI only expands slash commands in the interactive TUI input path, not in the non-interactive/SDK prompt path.

This creates a meaningful gap: skills that work reliably in the interactive CLI (via auto-expansion) become unreliable when used programmatically through the SDK (dependent on model choosing to call the Skill tool).

extent analysis

TL;DR

Modify the query() API call to manually expand slash commands before passing the prompt to the Agent SDK.

Guidance

  • Investigate the query() API documentation for any existing support for expanding slash commands or handling skills.
  • Consider preprocessing the prompt to expand slash commands manually before passing it to the query() function, using the list of available slash commands from the init event.
  • Verify that the Skill tool is being called correctly for the intended skill by checking the session events and logs.
  • If manual expansion is not feasible, explore alternative approaches, such as using a different API endpoint or modifying the skill to handle literal slash commands.

Example

const availableSlashCommands = ['ask', 'jira', 'push']; // obtained from init event
const prompt = '/ask What does this function do?';
const expandedPrompt = expandSlashCommand(prompt, availableSlashCommands);
const q = query({
  prompt: expandedPrompt,
  options: {
    cwd: '/path/to/project',
    settingSources: ['user', 'project'],
    pathToClaudeCodeExecutable: '/usr/local/bin/claude',
  },
});

// Simple example of an expandSlashCommand function
function expandSlashCommand(prompt, availableSlashCommands) {
  for (const command of availableSlashCommands) {
    const regex = new RegExp(`^/${command} (.*)$`);
    const match = prompt.match(regex);
    if (match) {
      // Expand the slash command manually, e.g., by loading the skill content
      const skillContent = loadSkillContent(command);
      return `${skillContent} ${match[1]}`;
    }
  }
  return prompt; // Return the original prompt if no expansion is possible
}

Notes

The provided example is a simplified illustration and may require adjustments based on the actual implementation of the loadSkillContent function and the specific requirements of the skills.

Recommendation

Apply a workaround by manually expanding slash commands in the prompt before passing it to the query() API, as shown in the example. This approach allows for reliable skill invocation through the SDK, even if the CLI's auto-expansion is not triggered.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING