Skip to content

[Bug] Local mode: workspace/agent config wiped on every gateway restart #1601

@lauriskwan

Description

@lauriskwan

Summary

In local (OpenClaw embedded) mode, the manifest plugin wipes all configured agents, providers, and tier assignments on every gateway restart. After restarting, the dashboard shows no agents and LLM routing fails until the workspace is manually reconfigured.

Environment

  • Manifest plugin version: 5.45.1
  • Mode: local (embedded in OpenClaw)
  • DB: sql.js (SQLite in-memory with autoSave)
  • OS: Linux (Alibaba Cloud ECS)

Steps to Reproduce

  1. Install the manifest plugin in OpenClaw local mode
  2. Open the dashboard, create an agent, connect a provider, configure tier routing
  3. Restart the OpenClaw gateway (systemctl --user restart openclaw-gateway.service)
  4. Open the dashboard — agent is gone, provider config is gone, routing fails

Reproducible on every restart.

Root Cause

database.module.js configures TypeORM for local mode with:

{
    type: 'sqljs',
    location: dbPath,
    autoSave: true,
    synchronize: true,   // ← unsafe for persistent data
    migrationsRun: false,
}

synchronize: true causes TypeORM to compare the live DB schema against entity definitions on every startup. It detects foreign key constraint name mismatches between the names stored in the DB and the names TypeORM's DefaultNamingStrategy would generate for the same constraints:

Table FK name in DB TypeORM generates
agents FK_87e9fdd9a00cd5fa5768aa0e6be FK_69ff36c94a56814577689bb2c64
agent_api_keys (tenant_id) FK_25add637eabf3b78d8a46bc4976 FK_52705c7782990abec7a3ab7c77a
agent_api_keys (agent_id) FK_8c341005a4d7642cd4b0f53e134 FK_85631aafd981b6125f3afeb6207

These mismatches trigger TypeORM's recreateTable(). For SQLite, recreateTable follows this sequence:

  1. PRAGMA foreign_keys = OFF
  2. Create temporary_agents
  3. INSERT INTO temporary_agents SELECT * FROM agents ← data copied OK
  4. DROP TABLE agents ← cascade-deletes agent_api_keys (FK ON DELETE CASCADE)
  5. ALTER TABLE temporary_agents RENAME TO agents

Step 4 destroys agent_api_keys. TypeORM then also recreates agent_api_keys (same FK name mismatch), but the data is already gone. autoSave writes this empty state back to disk. On the next restart, the same sequence repeats.

This happens silently — no errors are logged, the server starts healthy, but all workspace configuration is lost.

Why This Doesn't Affect Cloud/Postgres Mode

The Postgres config in the same file correctly uses:

{
    type: 'postgres',
    synchronize: false,
    migrationsRun: true,   // ← correct approach
}

Local mode was not given the same treatment.

Fix

Change synchronize: true to synchronize: false in the local mode TypeORM config, and run schema changes through the existing migrations instead.

// database.module.js — local mode branch
 {
     type: 'sqljs',
     location: dbPath,
     autoSave: dbPath !== ':memory:',
     entities,
-    synchronize: true,
+    synchronize: false,
+    migrationsRun: true,
     migrationsRun: false,
     logging: false,
 }

The migration files already exist in the dist bundle and cover all schema changes. Enabling migrationsRun: true for local mode would apply them safely without touching existing data.

Workaround (until fixed)

Patch the compiled dist directly after installation:

sed -i 's/synchronize: true/synchronize: false/' \
  ~/.openclaw/extensions/manifest/dist/backend/database/database.module.js

Metadata

Metadata

Assignees

No one assigned

    Labels

    wontfixThis will not be worked on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions