can1357/oh-my-pi · error · ToolError
run URL repository does not match the provided repo
Error message
run URL repository does not match the provided repo
What it means
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.
Source
Thrown at packages/coding-agent/src/tools/gh-common.ts:238
* the host `gh` itself resolved from the remote.
*/
async function resolveRepoFromCwd(cwd: string, signal?: AbortSignal): Promise<string> {
const url = requireNonEmpty(await github.text(cwd, ["repo", "view", "--json", "url", "-q", ".url"], signal), "repo");
const repo = repoFromUrl(url);
if (!repo) {
throw new ToolError(`GitHub CLI returned an unrecognized repository URL: ${url}`);
}
return repo;
}
export async function resolveGitHubRepo(
cwd: string,
repo: string | undefined,
runRepo: string | undefined,
signal?: AbortSignal,
): Promise<string> {
if (repo && runRepo && !githubRepoSlugEquals(repo, runRepo)) {
throw new ToolError("run URL repository does not match the provided repo");
}
if (repo) {
return repo;
}
if (runRepo) {
return runRepo;
}
return resolveRepoFromCwd(cwd, signal);
}
/**
* Process-lifetime cache of `gh repo view` lookups keyed by absolute cwd.
* Avoids repeated `gh` chatter when the same protocol handler or tool call
* resolves the default repo many times in a row.
*View on GitHub (pinned to 9690622007)
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.
Example fix
// before await resolveGitHubRepo(cwd, "acme/api", "https://github.com/acme/api-fork/actions/runs/9"); // after await resolveGitHubRepo(cwd, "acme/api-fork", "https://github.com/acme/api-fork/actions/runs/9");
Defensive patterns
Strategy: validation
Validate before calling
function repoSlugFromRunUrl(url) {
const m = url.match(/^https:\/\/[^/]+\/([^/]+\/[^/]+)\//);
return m ? m[1] : null;
}
const slug = repoSlugFromRunUrl(runUrl);
if (repo && slug && repo.replace(/\.git$/, "").toLowerCase() !== slug.toLowerCase()) {
throw new Error("repo does not match run URL");
} Try / catch
try {
await resolveGitHubRepo(cwd, repo, runUrl);
} catch (err) {
if (err instanceof ToolError && err.message.includes("does not match the provided repo")) {
// derive repo from the run URL instead
repo = repoSlugFromRunUrl(runUrl);
} else throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Provider delete URL must not embed an account credential
- ${destination} returned an invalid upload URL
- Destination option endpoint must be an absolute URL
- Destination option endpoint must use HTTP or HTTPS
- Destination option ${optionName} must be an absolute HTTP UR
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/91724ec6ab19c0d1.
Report an issue: GitHub.