This is the record of an abcd-managed repository

abcdBetav0.16.2 · 2026-11-06

Development record

abcd's own test suite leaves a dangling symlink on PATH, and `ahoy install` then refuses to complete for ever, with no supported way to clear it.

issueresolvedmajoriss-2609100506256636

abcd's own test suite leaves a dangling symlink on PATH, and ahoy install then refuses to complete for ever, with no supported way to clear it.

Found at the very start of adopting abcd in a managed repository. abcd was not on PATH at all, and the user-level bin entry was a symlink pointing into a deleted temp directory whose name is a Go test name from abcd's own ahoy install suite (a TestAhoyInstallAccepts… directory, with the numbered subdirectory a t.TempDir tree leaves behind). So a test run wrote a real symlink into the user's real bin directory and did not clean it up.

The consequence is worse than the litter. That directory is early on PATH, so every bare abcd … resolved to a broken link, including the command abcd's own SessionStart hook tells the operator to run. Detection reported it correctly as symlink.foreign and refused: "Resolve manually; ahoy refuses to clobber." That refusal is right in general — abcd must not delete a binary someone else installed — but the state is unreachable from inside the tool: there is no --force, no ahoy uninstall path that removes a foreign entry, and the gap is resolvable: false, so ahoy install can never finish. The only way out is a manual removal the operator has to be told to run.

Two things worth separating. Refusing to clobber a foreign symlink is correct. Refusing to clobber a symlink that is DANGLING is not obviously correct: a link whose target does not exist runs nothing, shadows the real binary, and cannot be anyone's working install. abcd already reads the target to report it, so it already knows the target is missing.

Needed: (1) the test suite must not write into the user's real bin directory — point it at a temp bin dir; (2) treat a dangling symlink as replaceable, or offer an explicit override that names what it is replacing, so a repo can be adopted without shell surgery. Both are small; the first is the one that created the problem.

Grounds

  • pursued: we expect danglingness to be the right discriminator because a link resolving to nothing cannot be in use by anyone, so clearing it takes nothing from a user while ending a permanent wall; it is shown wrong if a dangling link is ever a deliberate placeholder someone intends to fill

Frontmatter

idiss-2609100506256636
typeissue
lifecycleresolved
severitymajor

mentions3