thedotmack/claude-mem · warning
Worker is ready but still reports a stale version; not recyc
Error message
Worker is ready but still reports a stale version; not recycling again in this hook invocation (one recycle per hook event)
What it means
Amplifier guard: a hook recycles a version-mismatched worker at most once per invocation. After readiness, warnIfVersionStillMismatched re-fetches the worker's health version; if it still differs from the plugin's version, this warning fires and the hook returns success anyway — recycling again in the same invocation would re-create a restart storm. The NEXT hook event retries the recycle.
Source
Thrown at src/shared/worker-utils.ts:429
await workerHttpRequest('/api/health', { timeoutMs: HEALTH_CHECK_TIMEOUT_MS });
} catch {
return true;
}
if (Date.now() - start >= timeoutMs) return false;
await new Promise<void>(resolve => setTimeout(resolve, 200));
}
}
/**
* Amplifier guard: a hook recycles a stale worker AT MOST once per
* invocation. If the worker that became ready still reports a mismatched
* version, warn and return — the NEXT hook event retries. Recycling again in
* the same invocation re-creates the restart storm.
*/
async function warnIfVersionStillMismatched(expectedPluginVersion: string): Promise<void> {
const observedVersion = await fetchWorkerHealthVersion();
if (observedVersion !== null && observedVersion !== expectedPluginVersion) {
logger.warn('SYSTEM', 'Worker is ready but still reports a stale version; not recycling again in this hook invocation (one recycle per hook event)', {
pluginVersion: expectedPluginVersion,
workerVersion: observedVersion,
});
}
}
async function isWorkerPortAlive(): Promise<boolean> {
let healthy: boolean;
try {
healthy = await isWorkerHealthy();
} catch (error: unknown) {
logger.debug('SYSTEM', 'Worker health check threw', {
error: error instanceof Error ? error.message : String(error),
});
return false;
}
if (!healthy) return false;
View on GitHub (pinned to 8bc631a71a)
Solutions
- Trigger one more hook event (open a new Claude session) — the next invocation retries the recycle; often self-heals.
- If it persists, use the logged pluginVersion vs workerVersion to locate duplicate installs and remove the stale one.
- Run npm run build-and-sync to rebuild and re-sync the plugin so resolved script and version agree.
- As a last resort, kill the worker manually so the next hook spawns a fresh one from the resolved script.
Defensive patterns
Strategy: retry
Validate before calling
const observed = await fetchWorkerHealthVersion();
if (observed !== null && observed !== expectedPluginVersion) {
// defer to next hook event — do NOT recycle again now
return;
} Type guard
const isVersionMismatch = (observed: string | null, expected: string): boolean => observed !== null && observed !== expected;
Prevention
- Run npm run build-and-sync after upgrades so plugin and worker builds stay in lockstep.
- Remove old copies of the plugin/worker scripts so resolution can't pick a stale build.
- Know that one stale-version warning right after upgrade is designed self-healing — the next hook retries.
When it happens
Trigger: A stale worker was killed and respawned, but the worker that came up still reports a version different from expectedPluginVersion — e.g. resolution picked an old worker-service build, or version constants drifted between plugin and worker.
Common situations: Upgrade left two copies of the plugin/worker scripts on disk; symlinked marketplace install lagging the built one; partial build-and-sync.
Related errors
- Generator paused for ${abortCategory}; preserving buffered w
- Transcript path missing or file does not exist: ${transcript
- Transcript file exists but is empty: ${transcriptPath}
- Invalid mode inheritance: ${modeId}. Only one level of inher
- Invalid mode ID: ${modeId}
AI-assisted analysis of thedotmack/claude-mem@8bc631a71a (2026-08-20).
Data as JSON: /api/errors/10460978b1c8d1b9.
Report an issue: GitHub.