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

  1. Ensure the server sets `opts.daemonPort` to its listening port when dispatching meta commands.
  2. If calling from tests, populate `opts: { daemonPort: <port> }` explicitly.
  3. 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

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


AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12). Data as JSON: /api/errors/0c1f3ff95d4776b4. Report an issue: GitHub.