garrytan/gstack · error · Error
skill command requires daemonPort in MetaCommandOpts (server
Error message
skill command requires daemonPort in MetaCommandOpts (server bug)
What it means
The `skill` meta-command needs a daemon port to reach the local skill daemon, read from `opts.daemonPort` (lines 1149-1153). If the caller (CLI or test harness) did not populate `MetaCommandOpts.daemonPort`, the command refuses to run rather than dialing a default port. The message explicitly labels this a server bug because opts should always be populated by the server.
Source
Thrown at browse/src/meta-commands.ts:1152
breadcrumbs,
headings,
interactive,
textBlocks,
totalWords,
};
});
return JSON.stringify(data, null, 2);
}
case 'domain-skill': {
return await handleDomainSkillCommand(args, bm);
}
case 'skill': {
const port = opts?.daemonPort;
if (port === undefined) {
throw new Error('skill command requires daemonPort in MetaCommandOpts (server bug)');
}
return await handleSkillCommand(args, { port });
}
case 'cdp': {
// Lazy import — cdp-bridge introduces module deps we don't want loaded
// for projects that never use the CDP escape hatch.
const { handleCdpCommand } = await import('./cdp-commands');
return await handleCdpCommand(args, bm);
}
case 'memory': {
// Lazy import — pulls in cdp-bridge + memory-snapshot + buffer accessors
// that aren't useful for projects that never run the diagnostic.
const { handleMemoryCommand } = await import('./memory-command');
return await handleMemoryCommand(args, bm);
}
View on GitHub (pinned to 94993f7401)
Solutions
- Ensure the server sets `opts.daemonPort` to its listening port when dispatching meta commands.
- If calling from tests, populate `opts: { daemonPort: <port> }` explicitly.
- If no daemon is running, start it (or use `domain-skill` instead, which doesn't need the port).
Example fix
// before
await handleMetaCommand('skill', args, bm, shutdown, tokenInfo, { executeCommand });
// after
await handleMetaCommand('skill', args, bm, shutdown, tokenInfo, { executeCommand, daemonPort: 7777 }); Defensive patterns
Strategy: validation
Validate before calling
if (opts?.daemonPort === undefined) {
throw new Error('Cannot dispatch skill command: daemonPort missing from MetaCommandOpts');
}
await handleMetaCommand('skill', args, bm, shutdown, tokenInfo, opts); Type guard
const hasDaemonPort = (o: MetaCommandOpts | undefined): o is MetaCommandOpts & { daemonPort: number } =>
typeof o?.daemonPort === 'number'; Prevention
- Centralize MetaCommandOpts construction in the server and assert daemonPort is set.
- In tests, always populate `opts.daemonPort` — treat it as required for `skill`.
- Unit-test the opts builder to fail fast if daemonPort is omitted.
When it happens
Trigger: Invoking `handleMetaCommand('skill', ...)` without passing `opts.daemonPort`, or the server failing to inject its listening port into the MetaCommandOpts.
Common situations: Test harnesses constructing `MetaCommandOpts` by hand; a refactor that stopped forwarding `daemonPort` from the server; CLI direct-dispatch path that bypasses server wiring.
Related errors
- commitSkill: tier "${opts.tier}" has no resolved path.
- commitSkill: a skill named "${opts.name}" already exists at
- token-registry already initialized with a different token; e
- rateLimit must be >= 0
- expiresSeconds must be >= 0 or null
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/0c1f3ff95d4776b4.
Report an issue: GitHub.