From 2c30b1f452df141e27ac8f072f0acdba831946dc Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Tue, 3 Mar 2026 03:35:17 +0000 Subject: [PATCH 1/2] fix: prevent server crash on missing repo and resolve credential helper by absolute path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fixes: 1. getRepoContext() called process.exit(1) when a repo wasn't found. This killed the daemon process when cloning a nonexistent repo, causing 'Empty reply from server' instead of a proper 404. Now throws errors instead — CLI callers still exit via the top-level catch handler, server callers catch and return 404. 2. The credential helper was referenced by bare name which requires it to be on PATH. Now resolves the absolute path to the sibling credential-main.js and invokes it via bun, so push auth works regardless of PATH configuration. --- src/cli/repo-context.ts | 12 ++++-------- src/git-remote/main.ts | 14 +++++++++++++- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/cli/repo-context.ts b/src/cli/repo-context.ts index d8af075..e43731f 100644 --- a/src/cli/repo-context.ts +++ b/src/cli/repo-context.ts @@ -43,8 +43,7 @@ export async function getRepoContext( }); if (records.length === 0) { - console.error(`Repository "${repoName}" not found. Run \`gitd init ${repoName}\` first.`); - process.exit(1); + throw new Error(`Repository "${repoName}" not found. Run \`gitd init ${repoName}\` first.`); } return extractContext(records[0], repoName); @@ -54,13 +53,11 @@ export async function getRepoContext( const { records } = await ctx.repo.records.query('repo'); if (records.length === 0) { - console.error('No repository found. Run `gitd init ` first.'); - process.exit(1); + throw new Error('No repository found. Run `gitd init ` first.'); } if (records.length > 1) { - console.error('Multiple repositories exist. Specify one with --repo , GITD_REPO env, or `git config enbox.repo `.'); - process.exit(1); + throw new Error('Multiple repositories exist. Specify one with --repo , GITD_REPO env, or `git config enbox.repo `.'); } const data = await records[0].data.json(); @@ -85,8 +82,7 @@ export async function getRepoContextId( function extractContext(record: any, name: string): RepoContext { const contextId = record.contextId; if (!contextId) { - console.error('Repository record has no contextId — this should not happen.'); - process.exit(1); + throw new Error('Repository record has no contextId — this should not happen.'); } const visibility = (record.tags?.visibility as 'public' | 'private') ?? 'public'; diff --git a/src/git-remote/main.ts b/src/git-remote/main.ts index 2aded30..46d62cc 100644 --- a/src/git-remote/main.ts +++ b/src/git-remote/main.ts @@ -20,11 +20,19 @@ * @module */ +import { fileURLToPath } from 'node:url'; +import { resolve } from 'node:path'; import { spawn } from 'node:child_process'; import { parseDidUrl } from './parse-url.js'; import { resolveGitEndpoint } from './resolve.js'; +/** Resolve the absolute path to the credential helper binary (sibling file). */ +function resolveCredentialHelper(): string { + const thisFile = fileURLToPath(import.meta.url); + return resolve(thisFile, '..', 'credential-main.js'); +} + // --------------------------------------------------------------------------- // Main // --------------------------------------------------------------------------- @@ -67,8 +75,12 @@ async function main(): Promise { ? 'remote-https' : 'remote-http'; + // The credential helper is a sibling .js file with a bun shebang. + // Use git's `!` syntax to invoke it via bun, which avoids + // needing the file to be +x or on PATH. + const credHelper = resolveCredentialHelper(); const child = spawn('git', [ - '-c', 'credential.helper=git-remote-did-credential', + '-c', `credential.helper=!bun '${credHelper}'`, '-c', 'credential.useHttpPath=true', helper, remoteName, endpoint.url, ], { From fcc6fff6c065c3175c213ef819f13af767755d2e Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Tue, 3 Mar 2026 03:40:47 +0000 Subject: [PATCH 2/2] chore: add changeset --- .changeset/fix-server-crash-and-cred-path.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fix-server-crash-and-cred-path.md diff --git a/.changeset/fix-server-crash-and-cred-path.md b/.changeset/fix-server-crash-and-cred-path.md new file mode 100644 index 0000000..3242e42 --- /dev/null +++ b/.changeset/fix-server-crash-and-cred-path.md @@ -0,0 +1,5 @@ +--- +"@enbox/gitd": patch +--- + +Fix daemon crash when cloning nonexistent repos (process.exit in server context) and resolve credential helper by absolute path so push auth works without PATH setup.