thedotmack/claude-mem · warning

Could not persist SessionEnd request for worker recovery

Error message

Could not persist SessionEnd request for worker recovery

What it means

On SessionEnd, when the worker cannot be reached immediately, the handler attempts to enqueue a deferred SessionEnd request so the worker can recover it later. If that persistence itself throws, this warning is logged. Crucially the hook still returns success ({ continue: true, exitCode: SUCCESS }) so the Claude Code session is never blocked — the cost is only a potentially lost session-end event.

Solutions

  1. Check ~/.claude-mem exists and is writable by the current user
  2. Free disk space if ENOSPC appears in the attached error
  3. Restart/rebuild the worker (npm run build-and-sync) so future SessionEnd events are delivered directly instead of deferred
  4. Clear a corrupted/locked queue store so persistence can succeed again

Example fix

// before
// queue dir unwritable silently
// after
mkdirSync(QUEUE_DIR, { recursive: true }); // ensure state dir exists before enqueue
Defensive patterns

Strategy: try-catch

Validate before calling

const stateDir = path.join(os.homedir(), '.claude-mem');
if (!existsSync(stateDir)) mkdirSync(stateDir, { recursive: true });
accessSync(stateDir, fsConstants.W_OK);

Try / catch

try {
  enqueueDeferredSessionEnd({ contentSessionId: sessionId, platformSource });
} catch (e) {
  logger.warn('HOOK', 'Could not persist SessionEnd request for worker recovery', { sessionId }, e instanceof Error ? e : new Error(String(e)));
  // still return success — never block the session
}

Prevention

When it happens

Trigger: enqueueDeferredSessionEnd throws — e.g. the queue/persistence directory is unwritable, disk full, DB locked, or the persistence layer throws on serialize. Raised during execute() of the SessionEnd hook while the worker is unavailable.

Common situations: Full disk or ~/.claude-mem directory permission problems; SQLite lock contention from another worker; corrupted queue store; running the hook in a sandbox without write access to the state dir.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/5584b5c8f083216b. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/handlers/session-end.ts:59

        contentSessionId: sessionId,
        platformSource,
        reason: input.reason,
        cwd: input.cwd,
      },
      {
        workerStartupTimeoutMs: SESSION_END_WORKER_STARTUP_TIMEOUT_MS,
        timeoutMs: SESSION_END_REQUEST_TIMEOUT_MS,
      },
    );
    if (isWorkerFallback(result)) {
      try {
        enqueueDeferredSessionEnd({ contentSessionId: sessionId, platformSource });
        logger.debug('HOOK', 'Session-end request persisted for worker recovery', {
          sessionId,
          platformSource,
        });
      } catch (error) {
        logger.warn('HOOK', 'Could not persist SessionEnd request for worker recovery', {
          sessionId,
          platformSource,
        }, error instanceof Error ? error : new Error(String(error)));
      }
      return { continue: true, suppressOutput: true, exitCode: HOOK_EXIT_CODES.SUCCESS };
    }

    logger.debug('HOOK', 'Session-end request queued, exiting hook');
    return { continue: true, suppressOutput: true, exitCode: HOOK_EXIT_CODES.SUCCESS };
  },
};

View on GitHub (pinned to d8bc9755e7)