JiuwenClaw is an open-source Python AI agent platform with a multi-agent team mode, a web UI, and support for local LLM backends via Ollama. Installing it from source is straightforward — until it isn't. This post documents every error I hit setting it up on Ubuntu and exactly how I resolved each one.
The Setup
- Ubuntu, Intel Ultra 7 165H, RTX 4070 8GB
- Ollama running locally with
qwen3:8b - JiuwenClaw 0.1.11 installed from source via
uv
Error 1: GitHub Rejects Your Password
fatal: could not read Username for 'https://github.com': No such device or address
GitHub dropped password authentication for git operations in 2021. You need a Personal Access Token (PAT).
Fix: Generate a PAT at https://github.com/settings/tokens (tick the repo scope), then embed it in the clone URL:
git clone https://USERNAME:TOKEN@github.com/openJiuwen-ai/jiuwenclaw /path/to/dest
If your username is an email address containing @, URL-encode it as %40 — otherwise git misparses the URL and rejects it with a cryptic port number error:
URL rejected: Port number was not a decimal number between 0 and 65535
# Correct for email usernames
git clone https://user%40domain.com:TOKEN@github.com/openJiuwen-ai/jiuwenclaw /path/to/dest
Also configure the credential store so you only do this once:
git config --global credential.helper store
Error 2: jiuwenclaw-init Hangs or Crashes When Run Non-Interactively
EOFError: EOF when reading a line
The init script prompts for language preference interactively. When run via a non-interactive shell (or via Claude Code's ! command prefix), there is no TTY and it crashes immediately.
Fix: Run jiuwenclaw-init directly in your terminal with the virtual environment activated — not via any automation layer:
source .venv/bin/activate
jiuwenclaw-init
Error 3: Startup Fails with dist directory not found
dist directory not found: /home/user/.jiuwenclaw/web/dist
[start_services] web exited with code 1
Source installs do not ship the pre-built frontend. The web/dist directory is in .gitignore and must be built manually.
Fix:
cd jiuwenclaw/web
npm install
npm run build
cp -r dist ~/.jiuwenclaw/web/dist
The build takes about 3 seconds. You only need to redo this if the frontend source changes (e.g. after a git pull).
Error 4: team must be a non-empty array
ValueError: team must be a non-empty array
This is thrown by the config parser when modes.team in config.yaml is written as a named mapping (dict) instead of a list. The web UI expects an array.
Wrong:
modes:
team:
my_team: # dict key — causes the error
team_name: my_team
Correct:
modes:
team:
- team_name: my_team # list item — works
lifecycle: persistent
This error also appears if the UI saves an empty team list after you delete all teams. Always ensure at least one team entry exists before saving.
Error 5: Team Configuration Shows Stale or Empty Data After Editing config.yaml
You edit config.yaml directly, restart the server, refresh the browser — and the Team Configuration panel still shows old data or nothing at all.
Root cause: The web UI does not read team configuration back from the server. The config.get WebSocket call only returns environment variable values. Team data is stored exclusively in browser localStorage under the key jiuwenclaw_agents_teams_cache. Direct edits to config.yaml are invisible to the UI until you also update localStorage.
Fix: Seed localStorage via the browser console. Because the JiuwenClaw frontend runs on localhost:5173, a plain fetch() from the same origin works — but loading a file from a different port requires CORS headers.
Start a CORS-enabled local file server:
python3 -c "
from http.server import HTTPServer, SimpleHTTPRequestHandler
import os
class CORSHandler(SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Access-Control-Allow-Origin', '*')
super().end_headers()
def log_message(self, *a): pass
os.chdir('/tmp')
HTTPServer(('127.0.0.1', 8765), CORSHandler).serve_forever()
" &
Place your team JSON in /tmp/jw_setup.js as a single localStorage.setItem(...) call, then run in the browser console on http://localhost:5173:
fetch('http://localhost:8765/jw_setup.js').then(r=>r.text()).then(code=>eval(code))
Refresh the page. The team config will appear. Click Save to write it back to config.yaml.
Why not just paste the JSON directly in the console? A multi-line paste causes SyntaxError: string literal contains an unescaped line break because the browser console treats each line as a separate statement. The file-serving approach sidesteps this completely.
Why not use Python's built-in http.server? It works for serving files but does not add Access-Control-Allow-Origin headers, so the browser blocks the fetch with a CORS error even though the status code is 200. You need the custom subclass shown above.
Error 6: kill Exit Code 1 After Stopping Orphaned Processes
kill 80613 80615 && ss -tlnp | grep 19001 || echo "Ports clear"
# Ports clear ← correct, but exit code was 1
The ss | grep returns exit code 1 when it finds nothing (standard grep behaviour), which causes the && chain to short-circuit. The ports were actually clear — the message was correct.
Fix: Use ; echo rather than || echo if you want to see the grep output regardless, or check the port state with a separate command after killing.
Summary
| Error | Cause | Fix |
|---|---|---|
| GitHub auth failure | Password auth removed 2021 | Use PAT in clone URL |
@ in username breaks URL |
Git misparses the host | URL-encode @ as %40 |
jiuwenclaw-init EOFError |
No interactive TTY | Run directly in terminal |
dist directory not found |
Frontend not built | npm install && npm run build && cp -r dist ~/.jiuwenclaw/web/dist |
team must be a non-empty array |
modes.team is a dict not a list |
Use - team_name: list syntax |
| Team config not visible in UI | UI reads localStorage, not config.yaml |
Seed localStorage via CORS fetch |
| CORS error on fetch | Default http.server adds no CORS headers |
Use custom handler with Access-Control-Allow-Origin: * |
kill exit code 1 |
grep exits 1 on no match |
Separate the kill and verify commands |
JiuwenClaw is a capable platform once it's running — the team mode with local Ollama models works well for multi-agent engineering workflows. The setup friction is mostly undocumented edge cases that are easy to fix once you understand the architecture.
No comments:
Post a Comment