Windows: peers.py inbox read crashes on os.O_NONBLOCK (bare use; defensive getattr form already used elsewhere) — and the read receipt is persisted before the crash
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
- #5512 @Jah-yee による — マージされずにクローズ
評価
調査の方向性
Start with loopx/control_plane/collaboration/peers.py at input_readiness() and compare its os.O_NONBLOCK use with the defensive forms in loopx/collaboration_mcp.py and loopx/control_plane/todos/completion_result.py. Reproduce on Windows with an inbox brief containing inputs; done means the read no longer crashes and the persisted receipt behavior is understood.
索引モデルが issue の本文から書いたものです。
説明
Summary
On Windows, peers.py's inbox read path crashes unconditionally whenever a peer request brief carries inputs, because input_readiness() uses os.O_NONBLOCK — an attribute that does not exist on Windows. Two properties make this worse than a plain crash:
- It is on the main read path (
read_inbox()→input_readiness(), peers.py), triggered by any brief with staged inputs — including the brief shapes in this repo's own test fixtures. - The read receipt is persisted before the crash. After the AttributeError, an after-the-fact look at
reads/<request_id>.jsonshows a recorded read (kind=receiver_cli_read,read_atset) even though the read actually failed — the receipt systematically misreports the outcome.
A one-line fix matches the pattern already used elsewhere in this same codebase (see below).
Repro (Windows, current main)
git rev-parse HEAD # d74554b48...
python -c "import os; print(hasattr(os, 'O_NONBLOCK'))" # False on win32
Then call the read path with a brief that has inputs (sandbox registry + workspace, minimal peers.request(...) followed by read_inbox(...)):
File "...\loopx\control_plane\collaboration\peers.py", line 547, in input_readiness
os.open(path, os.O_RDONLY | os.O_NONBLOCK)
AttributeError: module 'os' has no attribute 'O_NONBLOCK'
- Crash frame chain:
read_inbox→input_readiness(line 547 on current main; 523 on v1.2.2). - Before raising, the receipt
reads/<request_id>.jsonis already on disk withkind=receiver_cli_readandread_atwritten. - Briefs without an
inputskey do not hit the path (the staging guard returns early) — the failure is deterministic for any input-bearing brief on Windows, and retrying cannot succeed.
The fix already exists in this repo — twice
The defensive form is used elsewhere; only peers.py is bare (both verified on current main, git grep -n "O_NONBLOCK" upstream/main):
loopx/collaboration_mcp.py:867—getattr(os, "O_NONBLOCK", 0)loopx/control_plane/todos/completion_result.py:32—getattr(os, "O_NONBLOCK", 0)- vs.
loopx/control_plane/collaboration/peers.py:547— bareos.O_NONBLOCK
Suggested fix for peers.py (one line, consistent with those two precedents):
os.open(path, os.O_RDONLY | getattr(os, "O_NONBLOCK", 0))
On POSIX this is behavior-identical; on Windows the readiness probe degrades to a blocking open (or can be skipped, matching whatever the other call sites intend).
Impact notes
- Platform: Windows (any brief with
inputs); POSIX unaffected. - The persisted-but-failed receipt is the nastier half: any later audit of
reads/concludes the read succeeded. If there is a preferred outcome (e.g. record the read only after readiness succeeds, or record a failure kind), that would fix the misreport too — we're flagging it rather than prescribing, since the receipt-ordering may be intentional for crash recovery.
Our context
We hit this while operating a research squad on Windows against dsh 0.2.0rc2: three parallel workers all died on read_inbox with empty stdout/stderr, and the leftover receipts initially made it look like the reads had succeeded. Happy to turn the fix into a PR if the approach above is agreed — or an alternative if maintainers prefer dropping the readiness probe on Windows.
- 主要言語
- Python
- スター
- 6.2k
- フォーク
- 596
- 平均マージ
- 7時間 35分
- マージ済み PR(30日)
- 928
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
loopx-project/loopx のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
loopx-project/loopx#6842 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
loopx-project/loopx#6108 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
loopx-project/loopx#5688 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 60/100
loopx-project/loopx#5632 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
loopx-project/loopx#5443 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
loopx-project/loopx の issue をすべて見る
似ている issue
-
resource-submission validation-passed
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
hesreallyhim/awesome-claude-code#3214 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
room-commons replace accepts an empty old string and silently prepends the new text to the pageオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
doobidoo/mcp-memory-service#1650 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1〜3時間 初心者へのやさしさ 82/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
ml-explore/mlx-lm#2002 ·
メンテナーはふだん 2 日以内に返信