OpenClaw v2026.4.5 introduces a new model runtime (pi-coding-agent), plugin-based provider discovery, and memory/embeddings support. However, it includes breaking changes to Bedrock authentication and configuration that require manual steps.
Two upgrade paths:
- In-Place Upgrade — Preserves chat history, channel connections, skills, and config (recommended)
- Fresh Install — Delete and redeploy from scratch
| Area | v2026.3.24 (Legacy) | v2026.4.5 (Modern) |
|---|---|---|
| Config style | models.providers (explicit model list) |
plugins.entries (auto-discovers Bedrock models) |
| Auth field | "auth": "aws-sdk" (required) |
Ignored — auth resolved via environment variables |
| API field | "api": "bedrock-converse-stream" |
Still required if using legacy config; not needed with plugins |
| AWS env vars | Not required (SDK default chain works) | AWS_PROFILE=default required for EC2 IMDS auth |
| Install flags | --ignore-scripts on ARM64 |
Must NOT use --ignore-scripts (needs @buape/carbon) |
v2026.4.5's resolveAwsSdkAuthInfo() checks for AWS environment variables (AWS_PROFILE, AWS_ACCESS_KEY_ID, etc.) before falling through to the SDK default credential chain. On EC2 with IAM roles, no env vars are set — credentials come from IMDS — so auth fails with:
No API key found for amazon-bedrock.
Workaround: Set AWS_PROFILE=default in ~/.openclaw/.env.
Set these variables to match your deployment before running any commands below:
STACK_NAME="openclaw-bedrock" # ← your CloudFormation stack name
REGION="us-west-2" # ← your deployment regionPreserves all your data:
- Chat history and conversation state
- Channel connections (WhatsApp, Telegram, Discord, Slack)
- SOUL.md customizations, installed skills, cron jobs
- Gateway token (no re-authentication needed)
INSTANCE_ID=$(aws cloudformation describe-stacks \
--stack-name $STACK_NAME \
--query 'Stacks[0].Outputs[?OutputKey==`InstanceId`].OutputValue' \
--output text --region $REGION)
aws ssm start-session --target $INSTANCE_ID --region $REGION
sudo su - ubuntuopenclaw --version # Confirm current version before upgrading
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak
cp ~/.openclaw/.env ~/.openclaw/.env.bak 2>/dev/null || true
ls -la ~/.openclaw/*.bakexport NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
# Do NOT use --ignore-scripts (v2026.4.5 needs native modules)
npm install -g openclaw@2026.4.5 --timeout=300000
openclaw --versionREGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/region)
# .env loaded by gateway systemd service
printf 'AWS_PROFILE=default\nAWS_REGION=%s\nAWS_DEFAULT_REGION=%s\n' "$REGION" "$REGION" > ~/.openclaw/.env
# systemd user environment for non-service processes
mkdir -p ~/.config/environment.d
printf 'AWS_REGION=%s\nAWS_DEFAULT_REGION=%s\nAWS_PROFILE=default\n' "$REGION" "$REGION" > ~/.config/environment.d/aws.confOption A — Modern plugin-based config (recommended):
TOKEN=$(python3 << 'PYEOF'
import json, os
with open(os.path.expanduser('~/.openclaw/openclaw.json')) as f:
cfg = json.load(f)
print(cfg['gateway']['auth']['token'])
PYEOF
)
MODEL=$(python3 << 'PYEOF'
import json, os
with open(os.path.expanduser('~/.openclaw/openclaw.json')) as f:
cfg = json.load(f)
print(cfg['agents']['defaults']['model']['primary'].split('/')[-1])
PYEOF
)
cat > ~/.openclaw/openclaw.json << EOF
{
"gateway": {
"mode": "local",
"port": 18789,
"bind": "loopback",
"controlUi": { "enabled": true, "allowInsecureAuth": true },
"auth": { "mode": "token", "token": "$TOKEN" }
},
"plugins": {
"entries": {
"amazon-bedrock": { "enabled": true }
}
},
"agents": {
"defaults": {
"model": { "primary": "amazon-bedrock/$MODEL" },
"memorySearch": { "provider": "bedrock", "model": "amazon.titan-embed-text-v2:0" }
}
}
}
EOFOption B — Keep legacy config with minimal changes:
python3 << 'PYEOF'
import json, os, sys
cfg_path = os.path.expanduser('~/.openclaw/openclaw.json')
with open(cfg_path) as f:
cfg = json.load(f)
provider = cfg['models']['providers']['amazon-bedrock']
provider.pop('auth', None)
if 'api' not in provider:
print('ERROR: api field required — add: "api": "bedrock-converse-stream"')
sys.exit(1)
if 'baseUrl' not in provider:
print('ERROR: baseUrl field required')
sys.exit(1)
with open(cfg_path, 'w') as f:
json.dump(cfg, f, indent=2)
print('Config updated')
PYEOFImportant: With Option B, the
apifield ("bedrock-converse-stream") must remain. Without it, v2026.4.5 defaults to raw HTTP calls, causing "LLM request timed out" errors.
openclaw gateway install --force
systemctl --user daemon-reload
systemctl --user restart openclaw-gateway.serviceopenclaw --version
systemctl --user status openclaw-gateway.service --no-pager
journalctl --user -u openclaw-gateway.service -n 50 --no-pagerWarning: This destroys all user data — chat history, channel connections (must re-pair WhatsApp, Telegram, etc.), SOUL.md, skills, cron jobs, and gateway token. Even with
EnableDataProtection=true, the retained data volume must be manually reattached — the template always creates a new volume on redeploy.
aws cloudformation delete-stack --stack-name $STACK_NAME --region $REGION
aws cloudformation wait stack-delete-complete --stack-name $STACK_NAME --region $REGIONaws ssm delete-parameter \
--name "/openclaw/$STACK_NAME/gateway-token" \
--region $REGION 2>/dev/null || trueaws cloudformation create-stack \
--stack-name $STACK_NAME \
--template-body file://clawdbot-bedrock.yaml \
--parameters \
ParameterKey=KeyPairName,ParameterValue=none \
ParameterKey=OpenClawVersion,ParameterValue=2026.4.5 \
ParameterKey=OpenClawModel,ParameterValue=global.amazon.nova-2-lite-v1:0 \
ParameterKey=InstanceType,ParameterValue=c7g.large \
ParameterKey=CreateVPCEndpoints,ParameterValue=true \
--capabilities CAPABILITY_IAM \
--region $REGION
aws cloudformation wait stack-create-complete --stack-name $STACK_NAME --region $REGIONThe template automatically handles all v2026.4.5 configuration (modern plugin config, AWS_PROFILE=default, environment variables).
INSTANCE_ID=$(aws cloudformation describe-stacks \
--stack-name $STACK_NAME \
--query 'Stacks[0].Outputs[?OutputKey==`InstanceId`].OutputValue' \
--output text --region $REGION)
aws ssm start-session --target $INSTANCE_ID --region $REGION
sudo su - ubuntu
openclaw --version
systemctl --user status openclaw-gateway.serviceReconnect messaging channels through the Control UI — see DEPLOYMENT.md.
cat ~/.openclaw/.env # Should contain AWS_PROFILE=default
# If missing:
REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/region)
printf 'AWS_PROFILE=default\nAWS_REGION=%s\nAWS_DEFAULT_REGION=%s\n' "$REGION" "$REGION" > ~/.openclaw/.env
systemctl --user restart openclaw-gateway.serviceLegacy config missing api field:
python3 << 'PYEOF'
import json, os
cfg_path = os.path.expanduser('~/.openclaw/openclaw.json')
with open(cfg_path) as f:
cfg = json.load(f)
cfg['models']['providers']['amazon-bedrock']['api'] = 'bedrock-converse-stream'
with open(cfg_path, 'w') as f:
json.dump(cfg, f, indent=2)
print('Fixed')
PYEOF
systemctl --user restart openclaw-gateway.serviceReinstall without --ignore-scripts:
export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
npm install -g openclaw@2026.4.5 --timeout=300000
openclaw gateway install --force
systemctl --user daemon-reload && systemctl --user restart openclaw-gateway.servicecp ~/.openclaw/openclaw.json.bak ~/.openclaw/openclaw.json
cp ~/.openclaw/.env.bak ~/.openclaw/.env 2>/dev/null || true
export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
ARCH=$(uname -m); IGNORE_FLAG=""; [ "$ARCH" = "aarch64" ] && IGNORE_FLAG="--ignore-scripts"
npm install -g openclaw@2026.3.24 --timeout=300000 $IGNORE_FLAG
openclaw gateway install --force
systemctl --user daemon-reload && systemctl --user restart openclaw-gateway.service