Skip to content

Windows: engine state store silently falls back to in-memory (total data loss on restart) — relative ./data/ path + detached spawn without cwd #913

Description

@DaveCole

Summary

On native Windows (Option A install, per the docs), the iii engine runs purely in-memory
when launched via any process whose working directory isn't writable — most notably a Windows
scheduled task (default CWD C:\Windows\System32). All memories, sessions, and
observations are lost on every engine restart. There is no error or warning; agentmemory stop
even prints "Memories persisted to disk" while nothing was ever written.

Environment

  • agentmemory v0.9.27 (npm, global), iii engine v0.11.2 native binary at
    %USERPROFILE%\.local\bin\iii.exe (installed exactly per the Windows Option A docs)
  • Windows 11 Pro, Node v24
  • Worker started by a logon scheduled task running npx -y @agentmemory/agentmemory

Reproduction

  1. Install per Windows Option A; start the worker from a scheduled task (or any shell whose
    CWD is unwritable).
  2. memory_save a few memories; confirm smart-search recalls them.
  3. Kill and restart the engine (graceful agentmemory stop or force-kill — same result).
  4. Recall returns empty; GET /agentmemory/export shows memories: 0.
  5. Observe: no data/ directory was ever created anywhere on the system.

Root cause

Three pieces combine:

  1. Bundled iii-config.yaml uses relative state paths:

    - name: iii-state
      config:
        adapter:
          name: kv
          config:
            store_method: file_based
            file_path: ./data/state_store.db   # <-- relative

    (The iii-config.docker.yaml variant uses absolute /data/... — the cloud-deploy docs
    even note the entrypoint rewrites the config to "absolute /data paths", hinting this was a
    known footgun.)

  2. The CLI spawns the engine without setting a working directory (dist/cli.mjs):

    spawnEngineBackground(iiiBin, ["--config", configPath], "iii-engine");
    // ...
    const child = spawn(bin, spawnArgs, { detached: true, stdio: [...] });  // no cwd

    The engine inherits the parent's CWD — C:\Windows\System32 under a scheduled task.

  3. The engine fails open: when ./data/ can't be created (System32 is unwritable for a
    non-elevated process), the file-backed KV silently degrades to in-memory. No error
    surfaces to the worker, the health endpoint, or the user.

Even when the CWD is writable, the relative path means each launch context (shell A,
shell B, scheduled task, service) gets a different data/ directory — state appears to
"randomly" survive or vanish depending on where the engine happened to start.

Verified fix (user-side workaround)

Creating ~/.agentmemory/iii-config.yaml (which wins the documented config resolution:
AGENTMEMORY_III_CONFIG → cwd → ~/.agentmemory/ → package bundle) with absolute paths:

  - name: iii-state
    config:
      adapter:
        name: kv
        config:
          store_method: file_based
          file_path: C:/Users/<user>/.agentmemory/data/state_store.db
  - name: iii-stream
    config:
      adapter:
        name: kv
        config:
          store_method: file_based
          file_path: C:/Users/<user>/.agentmemory/data/stream_store

After this, state_store.db is created and a force-kill + restart retains all memories.

Suggested upstream fixes (any one of these prevents the silent loss)

  1. Ship the default config with absolute paths rooted at ~/.agentmemory/data/ (the CLI
    already templates configs per-platform; homedir() is available at spawn time), or
  2. Set cwd in spawnEngineBackground to a stable writable directory
    (~/.agentmemory/), so the relative path resolves consistently, and/or
  3. Fail loudly: if store_method: file_based can't open its path, the worker/CLI should
    surface an error (and agentmemory stop should not print "Memories persisted to disk"
    when the store is in-memory).

A startup log line stating the resolved absolute state-store path would also have made this
diagnosable in minutes instead of hours.

Impact

Likely affects every native-Windows user who runs the worker from a scheduled task or
service (the natural way to keep it running) — and intermittently affects everyone else,
since persistence depends on launch CWD.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions