{"record":{"id":"206aa62ed2b6ae0a","repo":"stablyai/orca","slug":"failed-to-resolve-default-remote-for-repo","errorCode":null,"errorMessage":"Failed to resolve default remote for repo.","messagePattern":"Failed to resolve default remote for repo\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/git/repo.ts","lineNumber":858,"sourceCode":"      .map((line) => line.trim())\n      .filter(Boolean)\n    if (remotes.includes('origin')) {\n      return 'origin'\n    }\n    if (remotes.length === 1) {\n      return remotes[0]\n    }\n    if (remotes.length === 0) {\n      throw new Error('Repo has no configured git remotes.')\n    }\n    throw new Error(\n      `Repo has multiple remotes (${remotes.join(', ')}) and no default is configured. Set branch.<default>.remote.`\n    )\n  } catch (error) {\n    if (error instanceof Error) {\n      throw error\n    }\n    throw new Error('Failed to resolve default remote for repo.')\n  }\n}\n\nexport async function searchBaseRefs(path: string, query: string, limit = 25): Promise<string[]> {\n  return (await searchBaseRefDetails(path, query, limit)).map((entry) => entry.refName)\n}\n\nexport async function searchBaseRefDetails(\n  path: string,\n  query: string,\n  limit = 25\n): Promise<BaseRefSearchResult[]> {\n  if (!Number.isInteger(limit) || limit <= 0) {\n    return []\n  }\n  const normalizedQuery = normalizeRefSearchQuery(query)\n\n  try {","sourceCodeStart":840,"sourceCodeEnd":876,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/git/repo.ts#L840-L876","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Investigate the upstream throw site — find what rejected with a non-Error and make it throw an Error instead.","If this is a test mock, have it reject with new Error(...) rather than a string.","In production, capture the original value via additional logging to identify the rogue thrower.","Do not silently handle this — a non-Error throw indicates a contract violation in the runner."],"exampleFix":"// before (test mock that triggers 1054)\nmockGitExec.rejects('boom')\n\n// after: reject with a real Error so getDefaultRemote surfaces the real class\nmockGitExec.rejects(new Error('boom'))","handlingStrategy":"try-catch","validationCode":"// This branch only fires when something threw a non-Error. The fix is upstream:\n// ensure gitExecFileAsync and any wrappers always throw/reject with Error instances.\n// No caller-side pre-validation can prevent a non-Error throw from the runner.","typeGuard":"function isWrappedNonErrorFailure(error: unknown): boolean {\n  return error instanceof Error && error.message === 'Failed to resolve default remote for repo.'\n}","tryCatchPattern":"try {\n  return await getDefaultRemote(repoPath)\n} catch (error) {\n  if (isWrappedNonErrorFailure(error)) {\n    // Capture and log the original non-Error source for diagnosis; rethrow a clean Error.\n    console.error('Non-Error thrown from git remote listing', error)\n    throw new Error('Unexpected failure resolving the default remote. Check git runner health.')\n  }\n  throw error\n}","preventionTips":["Ensure all runner wrappers throw Error instances, never strings or plain rejects.","In tests, reject mocks with new Error(...) so this defensive branch never fires.","Treat hitting this branch as a contract violation to investigate, not a normal error to handle."],"tags":["git","remote","defensive","non-error-throw"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}