stablyai/orca · error
normalizeGitErrorMessage(error, 'fetch')
Error message
normalizeGitErrorMessage(error, 'fetch')
What it means
gitFetch wraps its fetch --prune in a try/catch that rethrows new Error(normalizeGitErrorMessage(error, 'fetch')). The literal message is the source expression; the runtime message is the normalized fetch diagnostic. Because the operation is 'fetch' (not 'push'/'pull'), the push-specific non-fast-forward and submodule hints are skipped — you get auth, network, no-upstream, or the tail stderr line.
Source
Thrown at src/main/git/remote.ts:312
}
export async function gitFetch(
worktreePath: string,
pushTarget?: GitPushTarget,
options: GitRuntimeOptions = {}
): Promise<void> {
try {
if (pushTarget) {
const target = await validateGitPushTarget(worktreePath, pushTarget, options)
await gitExecFileAsync(
['fetch', '--prune', target.remoteName],
gitOptionsForWorktree(worktreePath, options)
)
return
}
await gitExecFileAsync(['fetch', '--prune'], gitOptionsForWorktree(worktreePath, options))
} catch (error) {
throw new Error(normalizeGitErrorMessage(error, 'fetch'))
}
}
View on GitHub (pinned to 1136503c6a)
Solutions
- Read the normalized message — auth, network, and no-upstream hints are pre-classified.
- For auth: refresh credentials for the target remote (or origin when no pushTarget is set).
- For network: retry once; fetch is idempotent and --prune is safe to re-run.
- Verify the target remote exists (git remote) before fetching when pushTarget is supplied — a removed fork remote fails here.
Example fix
// before
await gitFetch(worktreePath, { remoteName: 'fork', branchName: 'feat' })
// after: verify the remote exists, retry once on transient network failure
const remotes = await readRemotes(worktreePath)
if (!remotes.includes('fork')) throw new Error('Configure the fork remote first')
try { await gitFetch(worktreePath, { remoteName: 'fork', branchName: 'feat' }) }
catch (error) {
if (/(Network error|Could not resolve host)/.test(String(error))) await gitFetch(worktreePath, { remoteName: 'fork', branchName: 'feat' })
else throw error
} Defensive patterns
Strategy: retry
Validate before calling
import { getDefaultRemote } from './repo'
// Pre-check the target remote exists before fetching.
const { stdout } = await gitExecFileAsync(['remote'], gitExecOptions(worktreePath, {}))
const remotes = stdout.split('\n').map((l) => l.trim()).filter(Boolean)
const target = pushTarget?.remoteName ?? await getDefaultRemote(worktreePath).catch(() => null)
if (target && !remotes.includes(target)) throw new Error(`Remote '${target}' is not configured.`) Type guard
function isFetchAuth(error: unknown): boolean {
return error instanceof Error && error.message.startsWith('Authentication failed')
}
function isFetchNetwork(error: unknown): boolean {
return error instanceof Error && error.message.startsWith('Network error')
} Try / catch
try {
await gitFetch(worktreePath, pushTarget, options)
} catch (error) {
if (isFetchNetwork(error)) { await gitFetch(worktreePath, pushTarget, options) /* idempotent, safe to retry once */ }
else if (isFetchAuth(error)) { await refreshRemoteCreds(worktreePath); await gitFetch(worktreePath, pushTarget, options) }
else throw error
} Prevention
- Verify the target remote exists before fetching when supplying pushTarget.
- Refresh credentials on auth-class failures; fetch is safe to retry on transient network errors.
- Do not rename a remote without updating stored pushTargets.
When it happens
Trigger: Calling gitFetch(worktreePath, pushTarget, options) when the remote is unreachable, credentials are missing/expired, the named remote (pushTarget.remoteName) does not exist, the network drops mid-fetch, or a prune references a remote ref that is concurrently being deleted.
Common situations: Expired OAuth token / SSH key for the remote; offline or flaky network; a pushTarget pointing at a fork remote that was removed; fetching right after a remote rename without updating pushTarget; large repos on slow links hitting exec-level stalls.
Related errors
- normalizeGitErrorMessage(error, 'push')
- normalizeGitErrorMessage(error, 'push')
- normalizeGitErrorMessage(error, 'pull')
- Repo has no configured git remotes.
- Repo has multiple remotes (${remotes.join(', ')}) and no def
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/8460e28da2e3e9ce.
Report an issue: GitHub.