Problem
Pilot's drag-and-drop across trackers issues two concurrent PUTs (source tracker + destination tracker). This usually succeeds, but intermittently one of the PUTs returns 500 while the other returns 204.
Response body is 91 bytes (length reported by access log — content not captured in logs). No stack trace is written — the top-level error handler appears to swallow whatever threw.
Reproduction (on solid.social)
- Sign into a pod via pilot (test@jss on solid.social)
- Create two trackers (e.g.
home, work)
- Add a task to one
- Drag the task between trackers repeatedly
Roughly 1 in 5-10 drags will fail with "PUT failed: 500 Internal Server Error" in pilot's UI.
Sample from pm2 logs — two near-simultaneous PUTs, one 500, one 204:
req-36 OPTIONS /public/tracker/home-data.jsonld 204 t=0
req-37 OPTIONS /public/tracker/work-data.jsonld 204 t=+1ms
req-38 PUT /public/tracker/home-data.jsonld 500 36ms body=91B
req-39 PUT /public/tracker/work-data.jsonld 204 34ms
The failing PUT takes slightly longer (35.96ms vs 33.88ms) suggesting something blocking.
What we know
- Intermittent — same workflow often succeeds
- Concurrent — the two PUTs arrive within ~1ms
- Different resources — one fails, the other succeeds
- Auth OK — neither is 401/403
- Quota OK — well under default
- Not a client issue — pilot produces identical requests shape each time
What we need
- Add a top-level error hook in
server.js that logs the full stack on any 500, so the next occurrence gives us the exception
- Investigate
src/handlers/resource.js handlePut — possible races:
- ACL walker reading directory ACLs while another request writes siblings
- Notifications/events emitted during the second PUT encountering inconsistent state
- Did-nostr resolver throwing (saw
DID resolution error ... fetch failed in stderr near the time)
- Ensure concurrent-write safety: file write is atomic at OS level, but the read-stats-before-write pattern is racy
Priority
Medium — UX is visibly broken in pilot but retries work. Most pilot users won't hit it on first drag. Fix path is probably: better logging first, then whatever the actual race is second.
Env
Problem
Pilot's drag-and-drop across trackers issues two concurrent PUTs (source tracker + destination tracker). This usually succeeds, but intermittently one of the PUTs returns 500 while the other returns 204.
Response body is 91 bytes (length reported by access log — content not captured in logs). No stack trace is written — the top-level error handler appears to swallow whatever threw.
Reproduction (on solid.social)
home,work)Roughly 1 in 5-10 drags will fail with "PUT failed: 500 Internal Server Error" in pilot's UI.
Sample from pm2 logs — two near-simultaneous PUTs, one 500, one 204:
The failing PUT takes slightly longer (35.96ms vs 33.88ms) suggesting something blocking.
What we know
What we need
server.jsthat logs the full stack on any 500, so the next occurrence gives us the exceptionsrc/handlers/resource.jshandlePut — possible races:DID resolution error ... fetch failedin stderr near the time)Priority
Medium — UX is visibly broken in pilot but retries work. Most pilot users won't hit it on first drag. Fix path is probably: better logging first, then whatever the actual race is second.
Env
solid-apps.github.io/pilot/