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
- Install the manifest plugin in OpenClaw local mode
- Open the dashboard, create an agent, connect a provider, configure tier routing
- Restart the OpenClaw gateway (
systemctl --user restart openclaw-gateway.service)
- 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:
PRAGMA foreign_keys = OFF
- Create
temporary_agents
INSERT INTO temporary_agents SELECT * FROM agents ← data copied OK
DROP TABLE agents ← cascade-deletes agent_api_keys (FK ON DELETE CASCADE)
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
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
Steps to Reproduce
systemctl --user restart openclaw-gateway.service)Reproducible on every restart.
Root Cause
database.module.jsconfigures TypeORM for local mode with:synchronize: truecauses 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'sDefaultNamingStrategywould generate for the same constraints:agentsFK_87e9fdd9a00cd5fa5768aa0e6beFK_69ff36c94a56814577689bb2c64agent_api_keys(tenant_id)FK_25add637eabf3b78d8a46bc4976FK_52705c7782990abec7a3ab7c77aagent_api_keys(agent_id)FK_8c341005a4d7642cd4b0f53e134FK_85631aafd981b6125f3afeb6207These mismatches trigger TypeORM's
recreateTable(). For SQLite,recreateTablefollows this sequence:PRAGMA foreign_keys = OFFtemporary_agentsINSERT INTO temporary_agents SELECT * FROM agents← data copied OKDROP TABLE agents← cascade-deletesagent_api_keys(FK ON DELETE CASCADE)ALTER TABLE temporary_agents RENAME TO agentsStep 4 destroys
agent_api_keys. TypeORM then also recreatesagent_api_keys(same FK name mismatch), but the data is already gone.autoSavewrites 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:
Local mode was not given the same treatment.
Fix
Change
synchronize: truetosynchronize: falsein 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: truefor local mode would apply them safely without touching existing data.Workaround (until fixed)
Patch the compiled dist directly after installation: