Skip to content

shouldSyncSessions skips session data during full reindex triggered by session-start #44028

Description

@mrdeeds89

Bug Report: shouldSyncSessions skips session data during full reindex triggered by session-start

Summary

When a full reindex is triggered during a session-start sync (e.g., due to model mismatch after gateway restart), session transcript data is silently dropped from the index. The metadata still reports sources: ["memory", "sessions"], masking the data loss.

Version

OpenClaw 2026.3.8 (3caab92)

Steps to Reproduce

  1. Configure an agent with experimental.sessionMemory: true and sources: ["memory", "sessions"]
  2. Create a state where the agent's index metadata differs from the resolved config (e.g., embedding model mismatch — DB has text-embedding-3-small, config resolves to text-embedding-3-large)
  3. Restart the gateway
  4. Send a message to the agent (triggers warmSessionsync({ reason: "session-start" }))

Expected Behavior

The full reindex should include both memory files AND session transcripts, since the agent is configured with sources: ["memory", "sessions"].

Actual Behavior

The full reindex only syncs memory files. Session transcript data is dropped from the new index database. The index metadata still reports sources: ["memory", "sessions"], hiding the regression.

Root Cause

In src/memory/manager-sync-ops.ts, the shouldSyncSessions method has a priority bug:

shouldSyncSessions(params, needsFullReindex = false) {
    if (!this.sources.has("sessions")) return false;
    if (params?.force) return true;
    const reason = params?.reason;
    if (reason === "session-start" || reason === "watch") return false;  // ← returns before checking needsFullReindex
    if (needsFullReindex) return true;
    return this.sessionsDirty && this.sessionsDirtyFiles.size > 0;
}

The session-start early return (line 4) fires before the needsFullReindex check (line 5). This means when a full reindex is needed but triggered by a session starting, sessions are skipped.

The call chain:

  1. warmSession()sync({ reason: "session-start" })
  2. sync() detects needsFullReindex = true (model/provider/config mismatch)
  3. Calls runSafeReindex({ reason: "session-start" })
  4. runSafeReindex calls shouldSyncSessions({ reason: "session-start" }, true)
  5. Returns false because session-start short-circuits before needsFullReindex is checked
  6. New database is built with only memory files
  7. writeMeta() writes sources: ["memory", "sessions"] from config — masking the loss

Suggested Fix

Reorder the checks so needsFullReindex takes priority over the incremental-sync skip:

shouldSyncSessions(params, needsFullReindex = false) {
    if (!this.sources.has("sessions")) return false;
    if (params?.force) return true;
    if (needsFullReindex) return true;  // ← moved before session-start check
    const reason = params?.reason;
    if (reason === "session-start" || reason === "watch") return false;
    return this.sessionsDirty && this.sessionsDirtyFiles.size > 0;
}

The session-start / watch skip is correct for incremental syncs (don't burn resources on every session start), but should not apply when a full reindex is required — full reindexes need all data or the new database is incomplete.

Conditions That Trigger needsFullReindex

Any of these being true during a session-start sync will cause session data loss:

  • !meta — no metadata in DB
  • meta.model !== provider.model — embedding model change
  • meta.provider !== provider.id — embedding provider change
  • meta.providerKey !== providerKey — API key rotation
  • metaSourcesDiffer(meta, configuredSources) — sources config change
  • meta.chunkTokens !== settings.chunking.tokens — chunk size change
  • meta.chunkOverlap !== settings.chunking.overlap — chunk overlap change
  • vectorReady && !meta?.vectorDims — vector extension loaded after initial build

Impact

In our deployment (15 agents), this bug has caused recurring session data loss across 3 separate incidents over 3 days. Each time, manual openclaw memory index --force (which bypasses the bug via force: true) fixes it, but the regression returns after the next gateway restart because the underlying trigger conditions persist.

File Reference

dist/manager-Ch8Hmvy3.jsshouldSyncSessions method (corresponds to src/memory/manager-sync-ops.ts in source)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions