{"record":{"id":"91724ec6ab19c0d1","repo":"can1357/oh-my-pi","slug":"run-url-repository-does-not-match-the-provided-rep","errorCode":null,"errorMessage":"run URL repository does not match the provided repo","messagePattern":"run URL repository does not match the provided repo","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/gh-common.ts","lineNumber":238,"sourceCode":" * the host `gh` itself resolved from the remote.\n */\nasync function resolveRepoFromCwd(cwd: string, signal?: AbortSignal): Promise<string> {\n\tconst url = requireNonEmpty(await github.text(cwd, [\"repo\", \"view\", \"--json\", \"url\", \"-q\", \".url\"], signal), \"repo\");\n\tconst repo = repoFromUrl(url);\n\tif (!repo) {\n\t\tthrow new ToolError(`GitHub CLI returned an unrecognized repository URL: ${url}`);\n\t}\n\treturn repo;\n}\n\nexport async function resolveGitHubRepo(\n\tcwd: string,\n\trepo: string | undefined,\n\trunRepo: string | undefined,\n\tsignal?: AbortSignal,\n): Promise<string> {\n\tif (repo && runRepo && !githubRepoSlugEquals(repo, runRepo)) {\n\t\tthrow new ToolError(\"run URL repository does not match the provided repo\");\n\t}\n\n\tif (repo) {\n\t\treturn repo;\n\t}\n\n\tif (runRepo) {\n\t\treturn runRepo;\n\t}\n\n\treturn resolveRepoFromCwd(cwd, signal);\n}\n\n/**\n * Process-lifetime cache of `gh repo view` lookups keyed by absolute cwd.\n * Avoids repeated `gh` chatter when the same protocol handler or tool call\n * resolves the default repo many times in a row.\n *","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/gh-common.ts#L220-L256","documentation":"resolveGitHubRepo cross-checks a caller-supplied repo against a repo parsed from a run URL; if both are present and the slugs differ (case-insensitive compare via githubRepoSlugEquals), it throws this ToolError. It prevents acting on a run belonging to a different repository than requested.","triggerScenarios":"Calling resolveGitHubRepo (via tryResolveCurrentRepoFresh or repo accessor) with repo=\"owner/a\" while the run URL points at owner/b — e.g. a copied run URL from another repo combined with an explicit repo flag.","commonSituations":"Prompt supplies a run URL from a different repository than the agent's cwd repo; user typo in the repo slug or pasted the wrong workflow run link; fork where the run lives under the fork's slug but user passes upstream.","solutions":["Make the repo parameter match the repository in the run URL, or drop the explicit repo so it is inferred from the URL.","Verify the run URL belongs to the intended repository (compare owner/name in the link).","If working across forks, use the repo slug where the run actually exists."],"exampleFix":"// before\nawait resolveGitHubRepo(cwd, \"acme/api\", \"https://github.com/acme/api-fork/actions/runs/9\");\n// after\nawait resolveGitHubRepo(cwd, \"acme/api-fork\", \"https://github.com/acme/api-fork/actions/runs/9\");","handlingStrategy":"validation","validationCode":"function repoSlugFromRunUrl(url) {\n  const m = url.match(/^https:\\/\\/[^/]+\\/([^/]+\\/[^/]+)\\//);\n  return m ? m[1] : null;\n}\nconst slug = repoSlugFromRunUrl(runUrl);\nif (repo && slug && repo.replace(/\\.git$/, \"\").toLowerCase() !== slug.toLowerCase()) {\n  throw new Error(\"repo does not match run URL\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  await resolveGitHubRepo(cwd, repo, runUrl);\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"does not match the provided repo\")) {\n    // derive repo from the run URL instead\n    repo = repoSlugFromRunUrl(runUrl);\n  } else throw err;\n}","preventionTips":["Derive repo from the run URL rather than supplying both independently.","Sanity-check pasted run links against the current repository before use.","In forks, resolve the slug where the workflow actually ran."],"tags":["github","validation","url","mismatch"],"backgroundTag":"repo-url-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}