agentscope-ai / agentscope-ai/AgentTeams
[Bug] copaw worker can crash reading partially-written merged AGENTS.md during apply --zip update
- 主要言語
- Go
- スター
- 5.6k
- フォーク
- 692
- 平均マージ
- 5日 4時間
- マージ済み PR(30日)
- 23
説明
## Summary
`copaw/src/copaw_worker/worker.py:123` reads `AGENTS.md` from
`self.sync.local_dir` via `read_text()` with no retry or size check.
On `hiclaw apply worker --zip` against an **existing** copaw worker
(update path), this read appears to race with the sync's merged-file
write, producing `UnicodeDecodeError` mid multi-byte character; the
container exits with code 1 and only recovers on a manual
`docker start`.
## Environment
- HiClaw v1.1.0 GA, embedded mode, macOS Docker Desktop
- Worker: copaw runtime, package contains `config/SOUL.md` + `config/AGENTS.md`
- Reproduces on `apply --zip` *update* (existing worker), not on initial create
## Reproduction
1. Have a copaw worker already running with package A
2. Build package B with a modified `config/AGENTS.md`
3. `docker cp B.zip hiclaw-controller:/tmp/`
4. `docker exec hiclaw-controller hiclaw apply worker --zip /tmp/B.zip --name `
5. Within ~10s: `docker ps -a --filter name=hiclaw-worker-` shows `Exited (1)`
## Observed traceback (excerpt)
```
File ".../copaw_worker/worker.py", line 123, in start
(workspace_dir / name).write_text(src.read_text())
File ".../pathlib.py", line 1059, in read_text
return f.read()
UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 19964-19965:
unexpected end of data
```
## Investigation (evidence, not proof)
The race-with-sync explanation is the most consistent reading of the
evidence, but I have not done a source-level confirmation that the two
writers/readers actually overlap. What we observed:
- The merged `agents//AGENTS.md` in MinIO **is** valid UTF-8
when fetched post-mortem (`mc cp ...` after the crash; complete +
decodable end-to-end)
- File size at the error position (~19964 bytes) is suspiciously
close to the *previous* merged file size, consistent with
`worker.start()` reading partway into the new prefix during the
merger's write
- `docker start ` recovers cleanly; second boot sees the
fully-written file
## Suggested directions
1. **Atomic merge writes** — write the merged file to `*.tmp` then
`os.replace`, so partial reads are structurally impossible. Most
robust: addresses the root cause regardless of who reads when
2. **Bounded retry on `UnicodeDecodeError`** in `worker.py:123` —
surgical fallback that hardens the read site without changing the
sync side
3. Explicit "sync ready" signal that `worker.start()` waits on
(1) seems cleanest as a primary fix; (2) is reasonable defense-in-depth.
## Workaround (current)
After `apply --zip` update, wait ~10s. If the worker container shows
`Exited (1)`, run `docker start `. Second boot
succeeds because the merge is complete on disk by then. This is what
we currently document for our deployment (haopaw).
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
評価
この issue はまだ評価されていません。