garrytan/gstack · warning · Error
Usage: $B skill run <name> [--arg k=v]... [--timeout=Ns]
Error message
Usage: $B skill run <name> [--arg k=v]... [--timeout=Ns]
What it means
Thrown by handleRun when args[0] is falsy — the caller invoked `$B skill run` with no skill name. Identical shape to the show-usage guard but for the run path; parseSkillRunArgs is never reached because the name check short-circuits first.
Source
Thrown at browse/src/browser-skill-commands.ts:147
export function parseSkillRunArgs(args: string[]): ParsedRunArgs {
const passthrough: string[] = [];
let timeoutSeconds = DEFAULT_TIMEOUT_SECONDS;
for (let i = 0; i < args.length; i++) {
const a = args[i];
if (a.startsWith('--timeout=')) {
const n = parseInt(a.slice('--timeout='.length), 10);
if (!isNaN(n) && n > 0) timeoutSeconds = n;
continue;
}
passthrough.push(a);
}
return { passthrough, timeoutSeconds };
}
async function handleRun(args: string[], ctx: SkillCommandContext): Promise<string> {
const name = args[0];
if (!name) throw new Error('Usage: $B skill run <name> [--arg k=v]... [--timeout=Ns]');
const tiers = ctx.tiers ?? defaultTierPaths();
const skill = readBrowserSkill(name, tiers);
if (!skill) throw new Error(`Skill "${name}" not found.`);
const { passthrough, timeoutSeconds } = parseSkillRunArgs(args.slice(1));
const result = await spawnSkill({
skill,
skillArgs: passthrough,
trusted: skill.frontmatter.trusted,
timeoutSeconds,
port: ctx.port,
});
if (result.exitCode !== 0 || result.timedOut || result.truncated) {
const summary = result.truncated
? `truncated stdout at ${MAX_STDOUT_BYTES} bytes`
: result.timedOut
? `timed out after ${timeoutSeconds}s`View on GitHub (pinned to 94993f7401)
Solutions
- Re-run with a name: `$B skill run <name> [--arg k=v]... [--timeout=Ns]`.
- Put the name before any flags: `$B skill run hn-frontpage --arg k=v`.
- Run `$B skill list` to confirm the exact name spelling.
Example fix
// before $B skill run --timeout=30 // after $B skill run hn-frontpage --timeout=30
Defensive patterns
Strategy: validation
Validate before calling
function requireRunArgs(args: string[]): { name: string; rest: string[] } {
const name = args[0];
if (!name || name.startsWith('--')) {
throw new Error('Usage: $B skill run <name> [--arg k=v]... [--timeout=Ns]');
}
return { name, rest: args.slice(1) };
} Prevention
- Always place the skill name before any flags in `skill run`.
- Templates that build run commands should use a placeholder that errors if unsubstituted.
- Run `$B skill list` to copy exact names.
When it happens
Trigger: handleSkillCommand(['run'], ctx) or ['run','--timeout=30'] with no positional name before the flags — note parseSkillRunArgs would happily put '--timeout=30' into passthrough, so the name guard fires first to prevent a nonsense lookup.
Common situations: Agent constructs the run command from a template and forgets to substitute the name; user passes only flags; argument array was built by splitting an empty/whitespace-only name segment.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Usage: $B skill show <name>
- Usage: $B skill test <name>
- Usage: $B skill rm <name> [--global]
- Skill "${name}" not found in any tier.
- Skill "${name}" not found.
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/39c43c6976b9621c.
Report an issue: GitHub.