How to Migrate MOLTBOT and CLAWDBOT Environment Variables in OpenClaw
The Problem: Everything Was Silent
I upgraded OpenClaw to version 2026.3.22-beta.1 yesterday. The upgrade went smoothly - no errors, no warnings, OpenClaw started normally. But then I noticed something was wrong.
My configured API key wasn’t being used. My state directory was empty. My log level settings were ignored. Everything was running with defaults, as if I hadn’t configured anything at all.
The root cause? Legacy environment variables MOLTBOT_* and CLAWDBOT_* have been completely removed in this version. And they fail silently - no error message, no warning, just… nothing.
$ openclaw startStarting OpenClaw...State directory: ~/.openclaw (empty)API key: not setLog level: debug (default)Server started on port 3000
# My .env file had:# MOLTBOT_API_KEY=sk-prod-key-xxxxx# MOLTBOT_STATE_DIR=/var/lib/moltbot# MOLTBOT_LOG_LEVEL=warn
# But none of it was being read!This is the dangerous kind of breaking change - one that doesn’t tell you it broke.
What Changed in 2026.3.22-beta.1
Looking at the changelog, the removal was explicit:
Config/env: remove legacy CLAWDBOT_* and MOLTBOT_* compatibility env names.Config/state: remove legacy .moltbot state-dir and moltbot.json auto-detection/migration fallback.OpenClaw was originally called Moltbot (and briefly Clawdbot). For a long time, both naming conventions were supported. That transition period is over. Now:
- All
MOLTBOT_*environment variables are ignored - All
CLAWDBOT_*environment variables are ignored - The
~/.moltbotstate directory is no longer auto-detected - No migration fallback exists
If you have these anywhere in your infrastructure, they simply do nothing now.
How I Found All the Affected Places
The first thing I needed was a complete audit. Where was I using these legacy variables?
#!/bin/bash# Search for all legacy variable references
echo "Searching for MOLTBOT and CLAWDBOT references..."
# Search in project directorygrep -rn "MOLTBOT\|CLAWDBOT" .
# Search in Docker configsgrep -rn "MOLTBOT\|CLAWDBOT" docker-compose*.yml Dockerfile* .docker/
# Search in CI/CD configsgrep -rn "MOLTBOT\|CLAWDBOT" .github/ .gitlab-ci.yml .circleci/ Jenkinsfile*
# Search in shell scriptsgrep -rn "MOLTBOT\|CLAWDBOT" *.sh scripts/Running this revealed several locations I had forgotten about:
.env:3:MOLTBOT_API_KEY=sk-prod-key-xxxxx.env:4:MOLTBOT_STATE_DIR=/var/lib/moltbotdocker-compose.yml:12: - MOLTBOT_API_KEY=${MOLTBOT_API_KEY}.github/workflows/deploy.yml:27: MOLTBOT_API_KEY: ${{ secrets.MOLTBOT_API_KEY }}scripts/start-production.sh:8:export MOLTBOT_LOG_LEVEL=warnI had variables in five different places: .env file, Docker Compose, GitHub Actions, a shell script, and I still had the old ~/.moltbot state directory.
The Migration: Step by Step
Mapping Legacy to New Names
The naming convention is straightforward - everything is now OPENCLAW_*:
| Legacy | Current |
|---|---|
MOLTBOT_API_KEY | OPENCLAW_API_KEY |
MOLTBOT_STATE_DIR | OPENCLAW_STATE_DIR |
MOLTBOT_CONFIG_PATH | OPENCLAW_CONFIG_PATH |
MOLTBOT_LOG_LEVEL | OPENCLAW_LOG_LEVEL |
MOLTBOT_PORT | OPENCLAW_PORT |
MOLTBOT_HOST | OPENCLAW_HOST |
CLAWDBOT_* | OPENCLAW_* |
Updating Configuration Files
I started with the .env file:
# BeforeMOLTBOT_API_KEY=sk-prod-key-xxxxxMOLTBOT_STATE_DIR=/var/lib/moltbotMOLTBOT_LOG_LEVEL=warn
# AfterOPENCLAW_API_KEY=sk-prod-key-xxxxxOPENCLAW_STATE_DIR=/var/lib/openclawOPENCLAW_LOG_LEVEL=warnThen the Docker Compose file:
services: openclaw: image: openclaw/openclaw:latest environment: - MOLTBOT_API_KEY=${MOLTBOT_API_KEY} - MOLTBOT_STATE_DIR=/data/state volumes: - moltbot-state:/data/state
volumes: moltbot-state:services: openclaw: image: openclaw/openclaw:latest environment: - OPENCLAW_API_KEY=${OPENCLAW_API_KEY} - OPENCLAW_STATE_DIR=/data/state volumes: - openclaw-state:/data/state
volumes: openclaw-state:Then GitHub Actions secrets. This required going to the GitHub UI:
- Settings > Secrets and variables > Actions
- Create new secret
OPENCLAW_API_KEY - Update the workflow file:
- name: Deploy env: MOLTBOT_API_KEY: ${{ secrets.MOLTBOT_API_KEY }}- name: Deploy env: OPENCLAW_API_KEY: ${{ secrets.OPENCLAW_API_KEY }}Migrating the State Directory
The state directory was separate from environment variables. I had data in ~/.moltbot:
# Check what's in the old directoryls -la ~/.moltbot/
# Create new directorymkdir -p ~/.openclaw
# Copy state filescp -r ~/.moltbot/* ~/.openclaw/
# Verify migrationls -la ~/.openclaw/Alternatively, I could set OPENCLAW_STATE_DIR to keep using the old location:
export OPENCLAW_STATE_DIR=~/.moltbotBut I preferred to migrate to keep naming consistent.
A Common Mistake I Almost Made
I almost updated my .env file and called it done. But the audit showed I had variables in five places:
.envfiledocker-compose.yml- GitHub Actions workflow
- Production shell script
- State directory
If I had only updated .env, OpenClaw would still have been misconfigured in production and CI/CD. The silent failure nature of this change makes a comprehensive audit essential.
Another mistake would be mixing the naming:
OPENCLAW_API_KEY=xxxMOLTBOT_STATE_DIR=/data/state # This is ignored!Both variables need to use the OPENCLAW_ prefix.
Verification After Migration
After updating everything, I verified the migration:
# Check no legacy variables remaingrep -rn "MOLTBOT\|CLAWDBOT" .
# Expected output: nothing found
# Check new variables are setenv | grep OPENCLAW_
# Expected output:# OPENCLAW_API_KEY=sk-prod-key-xxxxx# OPENCLAW_STATE_DIR=/var/lib/openclaw# OPENCLAW_LOG_LEVEL=warn
# Verify state directoryls -la ~/.openclaw/
# Test OpenClaw configurationopenclaw config showFinally, I restarted all services:
# Docker Composedocker-compose down && docker-compose up -d
# Verify it's running with correct configdocker-compose logs openclaw | grep "State directory"# Should show: State directory: /var/lib/openclawAutomated Migration Script
For future reference, I wrote a migration script to handle this automatically:
#!/bin/bashset -e
echo "=== OpenClaw Environment Migration ==="
# Backup and migrate functionmigrate_file() { local file="$1" if [ -f "$file" ]; then cp "$file" "${file}.bak.$(date +%Y%m%d%H%M%S)" sed -i 's/MOLTBOT_/OPENCLAW_/g' "$file" sed -i 's/CLAWDBOT_/OPENCLAW_/g' "$file" sed -i 's/moltbot/openclaw/g' "$file" echo "Migrated: $file" fi}
# Common config filesfor file in .env .env.local .env.production docker-compose.yml docker-compose.yaml Dockerfile Dockerfile.prod; do migrate_file "$file"done
# Migrate state directoryif [ -d "$HOME/.moltbot" ] && [ ! -d "$HOME/.openclaw" ]; then cp -r "$HOME/.moltbot" "$HOME/.openclaw" echo "State directory migrated: ~/.moltbot -> ~/.openclaw"fi
echo ""echo "Migration complete! Review changes and restart services."Why This Breaking Change Happened
OpenClaw was renamed from Moltbot (and briefly Clawdbot) to better reflect its open-source nature. The dual-naming support was maintained for a transition period, but keeping it indefinitely adds:
- Code complexity for backward compatibility
- Confusion about which naming to use
- Inconsistent configurations across codebases
- Maintenance burden for deprecated paths
The clean break simplifies the codebase and gives users a single, clear naming convention. But the silent failure mode makes pre-upgrade auditing critical.
Key Takeaways
- Audit before upgrading - Run
grep -rn "MOLTBOT\|CLAWDBOT" .to find all affected files - Check everywhere -
.envfiles, Docker configs, CI/CD pipelines, shell scripts, Kubernetes manifests - Migrate both env vars and state - Environment variables and state directory are separate concerns
- Verify after migration - Use
openclaw config showto confirm configuration is correct - Restart services - Configuration changes require service restarts to take effect
The silent failure mode means you won’t know something is wrong until you notice OpenClaw behaving unexpectedly. A proactive audit prevents this.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments