agentscope-ai / agentscope-ai/AgentTeams

[Bug] copaw worker can crash reading partially-written merged AGENTS.md during apply --zip update

Offen
#711 4 Kommentare 0 Reaktionen 1 zugewiesene Person Beansprucht von @maplefeng-a Auf GitHub ansehen
area:worker-runtime
Vorherrschende Sprache
Go
Sterne
5.6k
Forks
692
Ø Merge
5 T. 4 Std.
Gemergte PRs (30 T.)
23

Beschreibung

## 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).

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.