The Empty Database Problem
After configuring memory search, you might try to inspect the SQLite database and find â nothing:
sqlite3 ~/.openclaw/memory/main.sqlite "SELECT COUNT(*) FROM embedding_cache;"Error: unable to open database "/home/azureuser/.openclaw/memory/main.sqlite":
unable to open database fileThis happens because the memory directory doesnât exist yet on the host. The gateway creates its database inside the container at /home/node/.openclaw/memory/, not on the host at /home/azureuser/.openclaw/memory/.
Understanding the Path Mapping
OpenClawâs Docker Compose typically mounts the hostâs ~/.openclaw into the container:
volumes:
- ~/.openclaw:/home/node/.openclawThis means:
- Host path:
/home/azureuser/.openclaw/memory/ - Container path:
/home/node/.openclaw/memory/ - Same files â but ownership and permissions must work for both the host user and the containerâs
nodeuser (UID 1000)
Step-by-Step Bootstrap
1. Create the Directory Structure
mkdir -p ~/.openclaw/memory
mkdir -p ~/.openclaw/memory/notes2. Set Permissions
The container runs as user node (UID 1000). The directories need to be readable and writable by that UID:
chmod 770 ~/.openclaw/memory
chmod 770 ~/.openclaw/memory/notes3. Fix Ownership
sudo chown -R 1000:1000 ~/.openclaw/memoryThis maps ownership to the containerâs node user. Without this, the gateway process canât create or write the SQLite database.
4. Restart the Gateway
docker compose restart openclaw-gateway5. Verify the Database Was Created
find ~/.openclaw/memory -maxdepth 2 -type f \
\( -name "*.sqlite" -o -name "*.db" \) -lsExpected output:
1670790 0 -rw-r--r-- 1 azureuser azureuser 0 Feb 25 23:37
/home/azureuser/.openclaw/memory/main.sqliteNote: The file may initially be 0 bytes. The gateway creates the file on startup but only initializes the schema when the first memory operation occurs.
Verifying Permissions Inside the Container
The most reliable way to verify is to test write access from inside the container:
docker exec -it openclaw-openclaw-gateway-1 sh -lc '
echo test > /home/node/.openclaw/memory/._write_test && \
ls -la /home/node/.openclaw/memory && \
rm -f /home/node/.openclaw/memory/._write_test
'Expected output:
total 16
drwxrwx--- 3 node node 4096 Feb 25 23:41 .
drwxrwxr-x 11 node node 4096 Feb 25 23:36 ..
-rw-r--r-- 1 node node 5 Feb 25 23:41 ._write_test
-rw-rw---- 1 node node 0 Feb 25 23:37 main.sqlite
drwxrwx--- 2 node node 4096 Feb 25 23:37 notesIf you see the ._write_test file, the container can write to the memory directory.
Inspecting the Containerâs File System
Before troubleshooting permissions, check what the gateway sees:
docker exec -it openclaw-openclaw-gateway-1 sh -lc '
ls -la /home/node/.openclaw && \
ls -la /home/node/.openclaw/memory || true
'A healthy installation shows:
drwxrwxr-x 11 node node 4096 .
drwx------ 3 node node 4096 agents
drwxr-xr-x 2 node node 4096 canvas
drwxr-xr-x 2 node node 4096 completions
drwx------ 2 node node 4096 credentials
drwxr-xr-x 2 node node 4096 cron
drwxrwxr-x 2 node node 4096 identity
drwx------ 2 node node 4096 logs
drwx------ 3 node node 4096 memory â Must be owned by node
-rw------- 1 node node 2810 openclaw.json
drwxrwxr-x 4 node node 4096 workspaceKey things to verify:
memorydirectory is owned bynode:nodememorydirectory has at leastrwxfor owneropenclaw.jsonis owned bynode(same UID)
Installing sqlite3 on the Host
If you want to inspect the database from the host, install sqlite3 first:
sudo apt install sqlite3Then query:
sqlite3 ~/.openclaw/memory/main.sqlite "PRAGMA journal_mode;"
# Expected: delete
sqlite3 ~/.openclaw/memory/main.sqlite \
"SELECT name FROM sqlite_master WHERE type IN ('table','index','trigger','view');"Warning: Donât query the SQLite file while the gateway is actively writing to it. Use
docker compose stop openclaw-gatewayfirst for safe inspection, or use thememoryCLI commands instead.
Using the CLI Instead of Raw SQLite
OpenClaw provides CLI commands for memory operations that are safer than raw SQLite access:
# Search memory
docker compose run --rm openclaw-cli memory search "your query"
# Reindex all memory files
docker compose run --rm openclaw-cli memory reindex
# List memory contents
docker compose run --rm openclaw-cli memory listCommon Permission Patterns
| Scenario | Fix |
|---|---|
main.sqlite is 0 bytes | Normal â schema created on first write |
Permission denied inside container | sudo chown -R 1000:1000 ~/.openclaw/memory |
| File exists but UID mismatch | Check containerâs UID: docker exec openclaw-openclaw-gateway-1 id |
| Directory doesnât exist in container | Volume mount may be wrong â check docker compose.yml |
| Database locked errors | Stop concurrent access; only one process should write |
The UID Mapping Gotcha
The most common issue is a UID mismatch between the host and container:
Host user (azureuser) = UID 1000
Container user (node) = UID 1000 â Must match!If your host user isnât UID 1000, you have two options:
Option A: Change ownership to the containerâs UID
sudo chown -R 1000:1000 ~/.openclaw/memoryOption B: Run the container with your host UID
# In docker-compose.yml
services:
openclaw-gateway:
user: "${UID}:${GID}"Backup Strategy
The SQLite database and notes directory contain all of your agentâs long-term memory. Include them in your backup plan:
# Backup memory store
tar czf openclaw-memory-backup-$(date +%Y%m%d).tar.gz \
~/.openclaw/memory/
# Restore
tar xzf openclaw-memory-backup-*.tar.gz -C ~/
