abhigyanpatwari/GitNexus · error
Git URLs must not include query strings or fragments
Error message
Git URLs must not include query strings or fragments
What it means
validateGitUrl forbids URLs containing a query string (?...) or fragment (#...). Such components are never meaningful for git remotes and can be used to smuggle parameters past validation, so URLs with parsed.search or parsed.hash are rejected outright.
Source
Thrown at gitnexus/src/core/net/url-guard.ts:29
/**
* Validate an outbound http(s) URL to prevent SSRF.
* Only allows https:// and http:// schemes. Blocks private/internal addresses,
* IPv6 private ranges, cloud metadata hostnames, and numeric IP encodings.
*/
export function validateGitUrl(url: string): void {
let parsed: URL;
try {
parsed = new URL(url);
} catch {
throw new Error('Invalid URL');
}
if (!['https:', 'http:'].includes(parsed.protocol)) {
throw new Error('Only https:// and http:// git URLs are allowed');
}
if (parsed.search || parsed.hash) {
throw new Error('Git URLs must not include query strings or fragments');
}
const host = parsed.hostname.toLowerCase();
// Block known dangerous hostnames (cloud metadata services)
if (BLOCKED_HOSTNAMES.has(host)) {
throw new Error('Cloning from private/internal addresses is not allowed');
}
// Strip IPv6 brackets if present (URL parser behavior varies across Node versions)
let normalizedHost = host;
if (host.startsWith('[') && host.endsWith(']')) {
normalizedHost = host.slice(1, -1);
}
// Check if this is an IPv6 address
// Use manual colon detection as fallback since isIP may return 0 for some
// normalized IPv6 forms (e.g. ::ffff:7f00:1)View on GitHub (pinned to 0d1aed942f)
Solutions
- Strip the query string and fragment before passing the URL (split at '?' and '#', keep the first part).
- Paste the bare clone URL from the repo's 'Clone' button rather than the browser address bar.
- Move credentials out of the URL — use an auth header/credential helper instead of ?token=... query params.
Example fix
// before
await cloneOrPull(`https://github.com/acme/api?tab=readme`, dest);
// after
const url = new URL('https://github.com/acme/api?tab=readme');
url.search = '';
url.hash = '';
await cloneOrPull(url.toString(), dest); Defensive patterns
Strategy: validation
Validate before calling
const cleaned = u.split('#')[0].split('?')[0];
const p = new URL(cleaned);
if (p.search || p.hash) throw new Error('url still has query/fragment'); Type guard
const isBareGitUrl = (u: string): boolean => {
try { const p = new URL(u); return !p.search && !p.hash; } catch { return false; }
}; Try / catch
try {
validateGitUrl(url);
} catch (err) {
if (err instanceof Error && err.message.includes('query strings or fragments')) {
throw new Error(`strip ?query/#fragment from ${url}`);
}
throw err;
} Prevention
- Always strip search/hash from URLs taken from browser address bars.
- Never pass credentials via query parameters.
- Validate configured remotes once at startup with the same rules.
When it happens
Trigger: Calling validateGitUrl (or its callers cloneOrPull / normalizedRegistry / sanitizedHttpUrl) with a URL that includes ?query, #fragment, or tokens pasted from a web UI (e.g. 'https://host/repo?tab=readme' or trailing '#readme').
Common situations: Copy-pasting a repo URL straight from a browser address bar (keeps #anchor or ?params); appending access tokens as query params; template strings accidentally leaving '?ref=...' in the URL.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Invalid URL
- Only https:// and http:// git URLs are allowed
- Invalid URL
- Only https:// and http:// git URLs are allowed
- must not include query strings or fragments
AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-09-08).
Data as JSON: /api/errors/eb0c854cb1f4f137.
Report an issue: GitHub.