{"record":{"id":"9919a205567e6f3c","repo":"stablyai/orca","slug":"invalid-pull-request-number-string-prnumber","errorCode":null,"errorMessage":"Invalid pull request number: ${String(prNumber)}","messagePattern":"Invalid pull request number: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/github/pr-head-tracking-ref.ts","lineNumber":47,"sourceCode":"      options.localGitExecOptions ?? { cwd: repo.path }\n    )\n    return\n  }\n  if (!sshGitProvider) {\n    throw new Error('SSH Git provider is not available. Reconnect to this target and try again.')\n  }\n  await sshGitProvider.fetchRemoteTrackingRef(repo.path, remote, branch, ref)\n}\n\nexport async function fetchGitHubPullRequestHeadRef(\n  repo: { path: string; connectionId?: string | null },\n  sshGitProvider: SshGitProvider | null | undefined,\n  remote: string,\n  prNumber: number,\n  options: { localGitExecOptions?: LocalGitExecOptions } = {}\n): Promise<string> {\n  if (!isValidReviewHeadNumber(prNumber)) {\n    throw new Error(`Invalid pull request number: ${String(prNumber)}`)\n  }\n  if (!isSafeReviewHeadFetchRemote(remote)) {\n    throw new Error('Pull request fetch remote must not start with \"-\".')\n  }\n  if (!repo.connectionId) {\n    const localGitExecOptions = options.localGitExecOptions ?? { cwd: repo.path }\n    const remoteComponent = await getReviewHeadRemoteComponent(remote, localGitExecOptions)\n    // Why: return the same path the fetch wrote so callers don't re-resolve identity.\n    const localRef = githubPullRequestHeadLocalRef(remoteComponent, prNumber)\n    await gitExecFileAsync(\n      ['fetch', '--no-tags', remote, `+refs/pull/${prNumber}/head:${localRef}`],\n      {\n        ...localGitExecOptions,\n        timeout: REVIEW_HEAD_FETCH_TIMEOUT_MS\n      }\n    )\n    return localRef\n  }","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/github/pr-head-tracking-ref.ts#L29-L65","documentation":"Thrown by fetchGitHubPullRequestHeadRef when isValidReviewHeadNumber rejects prNumber. The guard exists because prNumber is interpolated into a refspec (`+refs/pull/<n>/head:...`) and passed as a CLI argument; a malformed value could produce an invalid refspec or, worse, an argv-style token. Typical valid values are positive integers; anything else (0, negative, NaN, fractional, non-numeric) is refused.","triggerScenarios":"Caller passes 0, a negative number, NaN, undefined (coerced to 'undefined'), a fractional PR number, or a value parsed from a malformed URL/deep link; a UI bug sending a placeholder sentinel before the real PR loads.","commonSituations":"Deep-link handler routing `/pull/abc` into the fetch; UI placeholder 0 reaching the call before the PR resolves; serialized action with corrupted PR number.","solutions":["Validate prNumber is a positive integer at the call site before invoking fetchGitHubPullRequestHeadRef.","If the value comes from a URL or user input, parse with Number and guard with Number.isSafeInteger && n > 0.","Discard placeholder/sentinel values (0, -1) at the UI layer."],"exampleFix":"// before\nawait fetchGitHubPullRequestHeadRef(repo, provider, remote, rawNumber)\n\n// after\nif (!Number.isSafeInteger(rawNumber) || rawNumber <= 0) {\n  toast.error('Invalid PR number.')\n  return\n}\nawait fetchGitHubPullRequestHeadRef(repo, provider, remote, rawNumber)","handlingStrategy":"validation","validationCode":"function isValidPrNumber(n: unknown): n is number {\n  return typeof n === 'number' && Number.isSafeInteger(n) && n > 0\n}","typeGuard":"function isValidPrNumber(n: unknown): n is number {\n  return typeof n === 'number' && Number.isSafeInteger(n) && n > 0\n}","tryCatchPattern":"if (!isValidPrNumber(prNumber)) {\n  toast.error('Invalid PR number.')\n  return\n}\nawait fetchGitHubPullRequestHeadRef(repo, provider, remote, prNumber)","preventionTips":["Parse PR numbers from URLs with Number() and guard with Number.isSafeInteger && n > 0.","Discard UI placeholder values (0, -1, NaN) before they reach the fetch.","Validate at the deep-link / extension API boundary, not at the git call site."],"tags":["github","pull-request","validation","argv-injection","refspec"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}