stablyai/orca · error

Failed to resolve default remote for repo.

Error message

Failed to resolve default remote for repo.

What it means

getDefaultRemote wraps the git remote listing in a try/catch. If the catch sees an Error instance it rethrows it verbatim (cases 1052/1053); this branch only fires for a non-Error thrown value — a string, number, null, or a thenable that rejected with a non-Error. It is a defensive rewrap so callers always get an Error. In practice the git runner throws Errors, so reaching this branch signals something unusual upstream threw a non-Error.

Source

Thrown at src/main/git/repo.ts:858

      .map((line) => line.trim())
      .filter(Boolean)
    if (remotes.includes('origin')) {
      return 'origin'
    }
    if (remotes.length === 1) {
      return remotes[0]
    }
    if (remotes.length === 0) {
      throw new Error('Repo has no configured git remotes.')
    }
    throw new Error(
      `Repo has multiple remotes (${remotes.join(', ')}) and no default is configured. Set branch.<default>.remote.`
    )
  } catch (error) {
    if (error instanceof Error) {
      throw error
    }
    throw new Error('Failed to resolve default remote for repo.')
  }
}

export async function searchBaseRefs(path: string, query: string, limit = 25): Promise<string[]> {
  return (await searchBaseRefDetails(path, query, limit)).map((entry) => entry.refName)
}

export async function searchBaseRefDetails(
  path: string,
  query: string,
  limit = 25
): Promise<BaseRefSearchResult[]> {
  if (!Number.isInteger(limit) || limit <= 0) {
    return []
  }
  const normalizedQuery = normalizeRefSearchQuery(query)

  try {

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Investigate the upstream throw site — find what rejected with a non-Error and make it throw an Error instead.
  2. If this is a test mock, have it reject with new Error(...) rather than a string.
  3. In production, capture the original value via additional logging to identify the rogue thrower.
  4. Do not silently handle this — a non-Error throw indicates a contract violation in the runner.

Example fix

// before (test mock that triggers 1054)
mockGitExec.rejects('boom')

// after: reject with a real Error so getDefaultRemote surfaces the real class
mockGitExec.rejects(new Error('boom'))
Defensive patterns

Strategy: try-catch

Validate before calling

// This branch only fires when something threw a non-Error. The fix is upstream:
// ensure gitExecFileAsync and any wrappers always throw/reject with Error instances.
// No caller-side pre-validation can prevent a non-Error throw from the runner.

Type guard

function isWrappedNonErrorFailure(error: unknown): boolean {
  return error instanceof Error && error.message === 'Failed to resolve default remote for repo.'
}

Try / catch

try {
  return await getDefaultRemote(repoPath)
} catch (error) {
  if (isWrappedNonErrorFailure(error)) {
    // Capture and log the original non-Error source for diagnosis; rethrow a clean Error.
    console.error('Non-Error thrown from git remote listing', error)
    throw new Error('Unexpected failure resolving the default remote. Check git runner health.')
  }
  throw error
}

Prevention

When it happens

Trigger: A code path inside the try (gitExecFileAsync or the surrounding logic) rejected with a non-Error value (e.g. a custom legacy code path that throws a string, a malformed rejection from a mocked runner in tests, or a corrupted runner shim).

Common situations: Tests that mock gitExecFileAsync to reject with a plain string; an older runner shim that threw raw rejection values; a third-party override or monkey-patch that throws a non-Error; very rare in production — production paths throw Errors.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/206aa62ed2b6ae0a. Report an issue: GitHub.