From 2ad8cf558f82fcf67859552f0a100bd41e66a2a4 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Tue, 14 Apr 2026 23:24:23 +0200 Subject: [PATCH] fix: handle rm -r on session directories rm -r first unlinks each synthetic file in s/{id}/ before removing the directory. The remove handler was passing the file basename to SessionStore.Delete, which failed with "session not found". Treat /s/{id}/{file} removes as no-ops so rm -r can proceed to the directory removal, which triggers the actual session kill. Co-Authored-By: Claude Sonnet 4.6 --- internal/p9/server.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/p9/server.go b/internal/p9/server.go index 75c535e..bba7fc5 100644 --- a/internal/p9/server.go +++ b/internal/p9/server.go @@ -862,7 +862,15 @@ func (s *Server) remove(cs *connState, fc *plan9.Fcall) *plan9.Fcall { case strings.HasPrefix(path, "/t/"): err = s.toolStore.Delete(pathBase(path)) case strings.HasPrefix(path, "/s/") && path != "/s/new": - err = s.sessionStore.Delete(pathBase(path)) + // If path is /s/{id}/{file}, it's a synthetic session file — no-op so + // that "rm -r s/{id}" can proceed to remove the directory itself, which + // triggers the actual session kill via Delete({id}). + parts := strings.SplitN(strings.TrimPrefix(path, "/s/"), "/", 2) + if len(parts) == 2 { + err = nil // synthetic file; let rm -r continue + } else { + err = s.sessionStore.Delete(parts[0]) + } default: return errFcall(fc, "remove not supported") }