Skip to content

fix: daemon spawn, nonce replay, and server crash on missing repo#172

Merged
LiranCohen merged 3 commits intomainfrom
fix/error-ux
Mar 4, 2026
Merged

fix: daemon spawn, nonce replay, and server crash on missing repo#172
LiranCohen merged 3 commits intomainfrom
fix/error-ux

Conversation

@LiranCohen
Copy link
Contributor

Summary

Three bugs that prevent push from working end-to-end:

  1. Daemon spawn fails with EACCESfindGitdBin() returned a raw .ts path and spawn() tried to execute it directly. Now returns { command: 'bun', prefix: [path] } so the daemon is spawned via bun src/cli/main.ts serve.

  2. Every push gets 401createPushAuthenticator() tracked nonces and rejected reuse. Git reuses the same credentials for GET ref-discovery and POST receive-pack within a single push, so the second request always failed. Removed nonce tracking — token expiry (5 min) is sufficient.

  3. Server crashes on missing repogetRepoContext() called process.exit(1), killing the daemon when cloning a nonexistent repo ("Empty reply from server"). Now throws instead — existing try/catch in serve.ts returns proper 404.

Verified

Ran full E2E manually on this machine: gitd initgitd serve --foregroundgit addgit commitgit push -u origin main → success. Clone of nonexistent repo returns proper 404, daemon stays alive.

Build, test, lint

All pass: 1119 tests, 0 failures, 0 lint warnings.

Three bugs that prevent push from working:

1. findGitdBin() returned a raw .ts path that spawn() tried to execute
   directly, failing with EACCES. Now returns { command, prefix } so
   the daemon is spawned via `bun src/cli/main.ts serve`.

2. createPushAuthenticator() tracked nonces and rejected reuse. Git
   reuses the same credentials for GET ref-discovery and POST
   receive-pack within a single push, so every push got a 401 on the
   second request. Removed nonce tracking — token expiry is sufficient.

3. getRepoContext() called process.exit(1) in a server context, killing
   the daemon when cloning a nonexistent repo. Now throws instead.
resolveLocalDaemon tried to spawn a daemon even without a password,
which would always fail (vault can't unlock). Previously this failed
instantly (EACCES), but now that spawn works correctly it blocks for
15s before timing out. Skip the attempt entirely when no password is
available — this also fixes CI test timeouts in resolveGitEndpoint.
@LiranCohen LiranCohen merged commit 7108123 into main Mar 4, 2026
4 checks passed
@LiranCohen LiranCohen deleted the fix/error-ux branch March 4, 2026 19:27
@github-actions github-actions bot mentioned this pull request Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant