garrytan/gstack · warning · Error
Usage: $B skill rm <name> [--global]
Error message
Usage: $B skill rm <name> [--global]
What it means
Thrown by handleRm when args[0] is falsy — `$B skill rm` was invoked with no skill name. The --global flag is parsed only after this guard, so `$B skill rm --global` without a name still trips this error first.
Source
Thrown at browse/src/browser-skill-commands.ts:207
cwd: skill.dir,
stdout: 'pipe',
stderr: 'pipe',
env: process.env,
});
const exitCode = await proc.exited;
const stdout = proc.stdout ? await new Response(proc.stdout).text() : '';
const stderr = proc.stderr ? await new Response(proc.stderr).text() : '';
if (exitCode !== 0) {
throw new Error(`Skill "${name}" tests failed (exit ${exitCode}).\n${stderr}`);
}
return stderr || stdout || `tests passed for "${name}"`;
}
// ─── rm ─────────────────────────────────────────────────────────
function handleRm(args: string[], ctx: SkillCommandContext): string {
const name = args[0];
if (!name) throw new Error('Usage: $B skill rm <name> [--global]');
const isGlobal = args.includes('--global');
const tier: 'project' | 'global' = isGlobal ? 'global' : 'project';
const tiers = ctx.tiers ?? defaultTierPaths();
// For UX: if no project tier exists at all, default to global.
const effectiveTier: 'project' | 'global' = (tier === 'project' && !tiers.project) ? 'global' : tier;
const dst = tombstoneBrowserSkill(name, effectiveTier, tiers);
return `Tombstoned "${name}" (${effectiveTier} tier) → ${dst}\n`;
}
// ─── spawnSkill (load-bearing) ──────────────────────────────────
export interface SpawnSkillOptions {
skill: BrowserSkill;
skillArgs: string[];
trusted: boolean;
timeoutSeconds: number;View on GitHub (pinned to 94993f7401)
Solutions
- Re-run with a name: `$B skill rm <name>` or `$B skill rm <name> --global`.
- Run `$B skill list` to confirm the exact name and which tier it lives in.
- Remember rm tombstones rather than deletes — recovery is possible from <tier>/.tombstones/.
Example fix
// before $B skill rm --global // after $B skill rm hn-frontpage --global
Defensive patterns
Strategy: validation
Validate before calling
function requireRmArgs(args: string[]): { name: string; global: boolean } {
const name = args[0];
if (!name || name.startsWith('--')) {
throw new Error('Usage: $B skill rm <name> [--global]');
}
return { name, global: args.includes('--global') };
} Prevention
- Place the skill name before --global in `skill rm` invocations.
- Remember rm tombstones (move to <tier>/.tombstones/) rather than deleting.
- Validate args[0] is a name, not a flag, before dispatching.
When it happens
Trigger: handleSkillCommand(['rm'], ctx), ['rm',''], or ['rm','--global'] (the --global is treated as no name because args[0] is '--global' which is truthy but not a valid name — note this slips through the usage guard and would fail later in tombstoneBrowserSkill as 'not found'). The pure usage error fires only when args[0] is genuinely empty.
Common situations: Agent or user runs `$B skill rm --global` expecting it to be prompted for a name; a destructive-ops confirmation wrapper strips the name; argument array built incorrectly by a script.
Related errors
- Usage: $B skill show <name>
- Usage: $B skill run <name> [--arg k=v]... [--timeout=Ns]
- Usage: $B skill test <name>
- 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/8cb78468d550a9a8.
Report an issue: GitHub.