abhigyanpatwari/GitNexus · error
Clone target repo name ${expectedRepoName} does not match re
Error message
Clone target repo name ${expectedRepoName} does not match requested URL What it means
cloneOrPull throws this when an expectedRepoName option was supplied and the repository name derived from the clone URL (extractRepoName) does not match it. This prevents cloning a URL whose repo differs from the expected, name-pinned target — a supply-chain / typo protection. The check is purely lexical and runs before any filesystem work.
Source
Thrown at gitnexus/src/server/git-clone.ts:337
* (CodeQL js/second-order-command-line-injection).
*/
export async function cloneOrPull(
url: string,
targetDir: string,
onProgress?: (progress: CloneProgress) => void,
options?: CloneOrPullOptions,
): Promise<string> {
// Containment barrier — inline with the canonical path.relative idiom so
// CodeQL recognizes the sanitizer at every following filesystem and
// subprocess sink. The same `safeTarget` is used for every downstream
// path operation — no reassignment that the analyzer could lose track of.
//
// The lexical check runs before filesystem creation; realpath and symlink
// checks below run before pull/clone and again after clone completes.
const cloneRoot = path.resolve(options?.allowedCloneRoot ?? CLONE_ROOT);
const expectedRepoName = options?.expectedRepoName;
if (expectedRepoName !== undefined && expectedRepoName !== extractRepoName(url)) {
throw new Error(`Clone target repo name ${expectedRepoName} does not match requested URL`);
}
const safeTarget = path.resolve(targetDir);
if (expectedRepoName !== undefined && path.basename(safeTarget) !== expectedRepoName) {
throw new Error(`Clone target basename must match repository name ${expectedRepoName}`);
}
const rel = path.relative(cloneRoot, safeTarget);
if (rel === '' || rel.startsWith('..') || path.isAbsolute(rel)) {
throw new Error(`Clone target must be a subdirectory of ${cloneRoot}`);
}
// Always validate the requested URL — the prior shape only ran this in
// the code path where the repo was cloned. Now it runs unconditionally,
// preventing SSRF / blocked-host bypasses even when targetDir already exists.
if (options?.allowAutoSyncSsh) validateAutoSyncRemoteUrl(url);
else validateGitUrl(url);
await fs.mkdir(cloneRoot, { recursive: true });View on GitHub (pinned to 0d1aed942f)
Solutions
- Correct the url so its repo name matches expectedRepoName.
- Update expectedRepoName to the actual name of the repo at the URL.
- Drop expectedRepoName (pass undefined) if the name pin is not required for this call.
- Log/inspect extractRepoName(url) to see what name the URL actually yields and reconcile it with config.
Example fix
// before
await cloneOrPull({ url: 'https://host/org/wrong-name.git', expectedRepoName: 'right-name' });
// after
await cloneOrPull({ url: 'https://host/org/right-name.git', expectedRepoName: 'right-name' }); Defensive patterns
Strategy: validation
Validate before calling
import { extractRepoName } from './git-clone.js';
if (expectedRepoName !== undefined && extractRepoName(url) !== expectedRepoName) {
throw new Error(`URL ${url} does not match expected repo ${expectedRepoName}`);
}
await cloneOrPull({ url, expectedRepoName, targetDir }); Try / catch
try {
await cloneOrPull(opts);
} catch (err) {
if ((err as Error).message.startsWith('Clone target repo name')) {
console.error(`Configured repo name does not match URL ${opts.url}; fix config or URL.`);
}
throw err;
} Prevention
- Derive expectedRepoName from extractRepoName(url) in callers instead of storing it separately.
- Validate remote URLs against configured names in CI before deploy.
- Alert on repo renames at the host so pinned names stay current.
When it happens
Trigger: Calling cloneOrPull with both expectedRepoName and a url whose last path segment (minus .git) differs from expectedRepoName, e.g. url 'https://host/gitnexus.git' with expectedRepoName 'other-repo'.
Common situations: Caller derives the expected name from a config entry or a prior index but passes a stale/renamed URL; branch-sync code iterating remotes where one remote points at a fork with a different name; user-edited remote URLs after a repo rename on the host.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- must not include query strings or fragments
- must use an SSH URL on github.com, gitlab.com, or gitee.com
- host must be one of github.com, gitlab.com, or gitee.com
- path must include owner/repo without traversal
- repository name must use only letters, digits, ".", "_", or
AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-09-08).
Data as JSON: /api/errors/699eb636a0ea963e.
Report an issue: GitHub.