Skip to content

Troubleshooting

”Conflict. The container name is already in use”

Section titled “”Conflict. The container name is already in use””
Terminal window
docker rm -f devcontainer
docker compose up -d

The image may be outdated. Pull the latest and restart:

Terminal window
docker compose pull
docker compose up -d

The entrypoint seeds ~/.claude.json with onboarding flags. If missing:

Terminal window
echo '{"hasCompletedOnboarding": true}' > ~/.claude.json

Check which value is actually set:

Terminal window
echo "$ANTHROPIC_API_KEY"

Common causes:

  • LiteLLM proxy key missing or invalid — if you’re using proxy mode, make sure LITELLM_API_KEY in .env contains the correct proxy credential, then restart the container so the entrypoint can derive ANTHROPIC_API_KEY.
  • OAuth token or proxy mode mismatch — use exactly one auth mode. If CLAUDE_CODE_OAUTH_TOKEN is set, it takes precedence over LiteLLM proxy mode.

If using Claude Max OAuth, check that the auth credentials were seeded:

Terminal window
cat ~/.local/share/opencode/auth.json

The file should contain an "anthropic" key with your OAuth token. If missing, verify CLAUDE_CODE_OAUTH_TOKEN is set in .env and restart the container.

To reset OpenCode config: delete ~/.config/opencode/opencode.json and ~/.local/share/opencode/auth.json, then restart.

Check that your API key is set correctly:

Terminal window
echo "$ANTHROPIC_API_KEY"

Verify it works by making a direct call to your provider.

The model is determined by your provider and API key. Check your provider’s documentation for available models.

The gh CLI requires a GH_TOKEN environment variable. Add it to your .env file:

GH_TOKEN=ghp_your-token-here

Create a token at github.com/settings/tokens. Fine-grained tokens (recommended) or classic tokens with repo scope both work. Restart the container after updating .env.

When GH_TOKEN is set, the entrypoint runs gh auth setup-git to configure the git credential helper for HTTPS. If HTTPS operations fail:

  1. Verify the token is valid: gh auth status
  2. Check the credential helper is configured: git config --global credential.helper
  3. Restart the container to re-run the entrypoint

Both authentication methods can coexist in the container:

  • SSH (SSH_PRIVATE_KEY in .env) — uses git@github.com: URLs. Required if your organization enforces SSH.
  • HTTPS (GH_TOKEN in .env) — uses https://github.com/ URLs. Simpler setup, no key management.

If both are configured, git uses whichever protocol matches the remote URL. To switch an existing clone:

Terminal window
# SSH to HTTPS
git remote set-url origin https://github.com/owner/repo.git
# HTTPS to SSH
git remote set-url origin git@github.com:owner/repo.git

”Permission denied” on /workspace or /home

Section titled “”Permission denied” on /workspace or /home”
Terminal window
sudo chown -R $(id -u):$(id -g) /workspace ~

The entrypoint automatically configures a user-writable npm global prefix at ~/.npm-global, so runtime npm install -g commands should work without sudo. If you still see EACCES errors, re-apply the fix manually:

Terminal window
mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
export PATH="$HOME/.npm-global/bin:$PATH"

The first build downloads the base image (~1 GB). Subsequent builds use cache. If slow every time:

Terminal window
docker builder prune
Terminal window
docker system prune -a --volumes

Warning: This removes all unused containers, images, and volumes — not just this project’s.

Can’t reach the internet from inside the container

Section titled “Can’t reach the internet from inside the container”
Terminal window
ping -c 1 8.8.8.8
nslookup google.com
curl -I https://github.com

If DNS fails, add to /etc/docker/daemon.json on the host:

{
"dns": ["8.8.8.8", "8.8.4.4"]
}

Then restart Docker.

Xvfb may not have started. Check inside the container:

Terminal window
ps aux | grep Xvfb

If not running, check that ENABLE_VNC is not set to false and restart the container.

”Cannot open display” or “No display” error

Section titled “”Cannot open display” or “No display” error”

The DISPLAY environment variable may not be set. Verify:

Terminal window
echo "$DISPLAY"

It should be :99. If empty, add DISPLAY=:99 to your .env or devcontainer.json and restart.

noVNC may not be running. Check inside the container:

Terminal window
ps aux | grep -E 'novnc|websockify'

If not running, verify ENABLE_VNC is true (the default) and check container logs:

Terminal window
docker compose logs dev | grep -i vnc

Change the host port in docker-compose.yml:

ports:
- "127.0.0.1:16080:6080"

The shared Chrome instance should be running on port 9222. Check inside the container:

Terminal window
# Is Chrome running?
curl http://localhost:9222/json/version
# Check Chrome logs
cat ~/.local/share/chrome-browser/chrome.log
# Verify the symlink
ls -la /opt/google/chrome/chrome
# Restart Chrome manually
. /usr/local/lib/chrome-browser.sh
start_chrome_browser

If the symlink is missing, pull the latest image and restart the container.

With the shared browser architecture, profile lock errors should not occur. If you see one, a stale Chrome process may be holding the lock:

Terminal window
# Kill any stale Chrome processes
pkill -f 'chrome.*remote-debugging-port' || true
# Remove the lock file
rm -f ~/.cache/chrome-devtools-mcp/chrome-profile/SingletonLock
# Restart Chrome
. /usr/local/lib/chrome-browser.sh
start_chrome_browser

The chrome-devtools-mcp server is now registered globally in ~/.claude/settings.json. If you have a per-repo .mcp.json that also registers it, you will see duplicate tools. Remove the chrome-devtools-mcp entry from per-repo .mcp.json files:

Terminal window
# Check for per-repo config
cat .mcp.json

Remove the chrome-devtools-mcp key from any per-repo .mcp.json to use the global registration.

Terminal window
docker compose down -v
docker rm -f devcontainer 2>/dev/null
docker compose pull
docker compose up -d

This destroys all data in volumes. You’ll need to re-clone repos and reconfigure tools.