Repository navigation
Description
What happened
On app/v3 (a687c92) and the land/app-v3 landing candidate (8511037), moving one chat back and forth between two
paired computers makes the copy-folder name longer on every move. After about three moves, the computer taking the
chat cannot create the folder:
create session directory: mkdir <home>/v3/projects/<very long name>: file name too long
The take has already acquired the hold, so the chat's turns are safe on the sync service and the other computer can
still take it back. On the computer that just took it, though, the window stays on Home and the chat cannot open.
dev b0dfe97 is not affected. Its take path files copies through takeCopyBucket, which hashes any name over
255 bytes, and reuses an existing local root. On app/v3 and land/app-v3, chatContinuer builds the bucket inline
with no cap, so land/app-v3 brings the bug to dev when it lands, unless the fix lands with it. #2287 contains a fix:
keep existing roots, reuse an origin copy's own name, and cap names at 240 bytes with a stable hash.
Replication
Deterministic (no model).
make build,go build -o modelstub ./test/remote/stub, and a local sync service:
bin/codeaf relay --listen <address> --store <empty folder>.- Make two throwaway homes, A and B. Each sets its own
HOME,CODEAF_HOMEandCODEAF_PROFILE_DIR, plus
CODEAF_SYNC_URL=<address>,CODEAF_BASE_URL=<stub address>/api/v1andOPENROUTER_API_KEY=stub, with
{"model.talk":"stub/scripted"}in the config. Pair them withcodeaf pair --code/codeaf pair <code>. - On A, start a chat in an ordinary project folder (for example
/tmp/w/project) and sendPROBE-ECHO one. - Alternate Continue here on Home: B takes it and sends
PROBE-ECHO, then A takes it back and sends, and so on, three
or four moves.- Today (app/v3, land/app-v3): a move fails with the
file name too longline above on the taker, and the window
stays on Home. - Expected: every move opens the chat. Folder names stay bounded and stable across moves.
- Today (app/v3, land/app-v3): a move fails with the
Where
chatContinuer'sBucketForincmd/codeaf/synctake.go(search"copy-"+encodeWorkspace(origin)). Compare
takeCopyBucketin the same file, which caps the name.- Separate note, every build including dev:
v3ProjectDirincmd/codeaf/chatv3_layout.gonames a chat's project
folderencodeWorkspace(workspace)with no length cap. A copy whose work folder path is very long (long home and
project paths) can exceed 255 bytes there on a single move, even with the bucket capped. That case does not grow per
move.
The fix
Bound every name derived from a path:
- the copy bucket: reuse an existing root, reuse an origin copy's own name, and cap with a stable hash;
- the project folder name, with the same cap.
Folder names must not change for chats that already have short ones.
Acceptance
- e2e: two homes on a local sync service (stub model), ten alternating moves of one chat. Every move opens the chat,
every journal is exact, and no folder-name component exceeds 255 bytes. - e2e: the control. Existing short folder names stay the same after the change.
- Unit: the bucket and project-folder names are bounded and stable for a nested copy origin, and unchanged for a
short one.
Activity
AbirAbbas commentedon Nov 10, 2026
Two notes from the fix (e70a2c1a4, which lands with the next dev re-merge into
land/app-v3). Both were read from code at land 8c06212 and dev ace7888, not run.1. A take that fails after the hand-over leaves the hold with the taker until the lease lapses.
giveBack(internal/syncsetup/take.go:399,:433-437).Dir.Releasedirectly (internal/syncsetup/take.go:346-389).cmd/codeaf/app_take.go):landTakerecords the chat as this computer's "even if opening it fails" (cmd/codeaf/app_take.go:177-178). AnappTakeOpenerror then returns with no release (:202-204).releaseUnusedTake(landinternal/tui3/homepanel_continue.go:629, dev:615) runs only for an automatic take that was cancelled or settled (internal/tui3/conversation_open.go:132-134, landhomepanel_continue.go:621-624). It does not run when opening fails for a take the person chose.internal/syncsetup/drive.go:49,:410).LeaseTTLMillis= 90 s (internal/clusterstate/types.go:10), and the other computer can then continue the chat again.ReleaseUnused; the app road needs the same inappTake.2.
v3ProjectDiris still uncapped (note only).encodeWorkspace(workspace)(cmd/codeaf/chatv3_layout.go:65) has no 255-byte cap, so a workspace whose encoded name is over 255 bytes still fails atos.MkdirAllwithcreate session directory: …(:66-67).cmd/codeaf: cap chatContinuer copy-bucket names at 255 bytes