thedotmack/claude-mem · error
Cannot lazy-spawn worker: worker-service.cjs not found in pl
Error message
Cannot lazy-spawn worker: worker-service.cjs not found in plugin/scripts
What it means
Lazy-spawn resolved the Bun runtime but resolvedScript.scriptPath is null — worker-service.cjs was not found under plugin/scripts for the current installation. The spawn aborts (returns false) and the hook event degrades, since there is no worker binary to launch.
Source
Thrown at src/shared/worker-utils.ts:557
pid: stalePidInfo.pid,
port: getWorkerPort(),
});
return false;
}
// The killed worker's PID file is left behind; the successor's boot
// removes it (validateWorkerPidFile returns 'stale' for a dead pid).
// Fall through to (re)spawn + readiness wait below.
}
const runtimePath = resolveWorkerRuntimePath();
const scriptPath = resolvedScript?.scriptPath ?? null;
if (!runtimePath) {
logger.warn('SYSTEM', 'Cannot lazy-spawn worker: Bun runtime not found on PATH');
return false;
}
if (!scriptPath) {
logger.warn('SYSTEM', 'Cannot lazy-spawn worker: worker-service.cjs not found in plugin/scripts');
return false;
}
// Spawn gate (worker-spawn-gate.ts): only ONE gated launcher — hook, MCP
// server, or the CLI restart fallback — may spawn at a time. (The dying
// worker's restart handoff in worker-shutdown.ts is deliberately NOT gated:
// it is the spawner for CLI-initiated restarts. Hook version recycles never
// trigger it — they SIGKILL the stale worker and spawn here.)
// Losing the lock never fails the hook; the loser skips its spawn and waits
// for the winner's worker on the existing port/readiness waits below. The
// winner holds the lock through the port-open wait (the spawn isn't "done"
// until the worker owns the port) and releases in finally on every exit
// path.
const spawnLockHeld = acquireSpawnLock();
try {
if (spawnLockHeld) {
logger.info('SYSTEM', 'Worker not running — lazy-spawning', { runtimePath, scriptPath });
View on GitHub (pinned to 8bc631a71a)
Solutions
- Run npm run build-and-sync in the claude-mem checkout — it rebuilds and syncs plugin scripts to the installed location.
- Verify plugin/scripts/worker-service.cjs exists in the installed plugin (~/.claude/plugins/marketplaces/thedotmack/…).
- If the marketplace copy is broken, reinstall the plugin from source.
Defensive patterns
Strategy: validation
Validate before calling
if (!existsSync(path.join(pluginDir, 'scripts', 'worker-service.cjs'))) {
// run the build before hooks try to lazy-spawn
failEarlyWithHint('Run npm run build-and-sync');
} Type guard
const hasWorkerScript = (resolved: { scriptPath: string | null } | null): resolved is { scriptPath: string } =>
resolved?.scriptPath != null; Prevention
- Always run npm run build-and-sync after cloning or upgrading the repo.
- Verify plugin/scripts/worker-service.cjs exists in the installed plugin directory.
- Treat a missing worker-service.cjs as a broken install — reinstall rather than retrying hooks.
When it happens
Trigger: The plugin install is incomplete: build artifacts never synced, scripts directory missing after an in-place upgrade, or version resolution unable to locate worker-service.cjs for the resolved plugin version.
Common situations: Cloning the repo without running the build; a partial plugin update leaving plugin/scripts empty; marketplace sync deleting files mid-update.
Related errors
- Worker is healthy but not ready; skipping hook API call
- Worker port did not open after lazy-spawn within the cold-bo
- Spawn-lock holder's worker port did not open within the cold
- Worker lazy-spawned but did not become ready before hook rea
- [uninstall] Worker shutdown attempt failed:
AI-assisted analysis of thedotmack/claude-mem@8bc631a71a (2026-08-20).
Data as JSON: /api/errors/731be39973246857.
Report an issue: GitHub.