abhigyanpatwari/GitNexus · error
Registry latest version is invalid
Error message
Registry latest version is invalid
What it means
After fetching and JSON-parsing the registry response, fetchLatest extracts the latest version from either parsed.version or parsed['dist-tags'].latest and validates it against STRICT_UPDATE_VERSION. If neither field is a string matching the strict semver pattern, it throws this error — the response was HTTP-valid JSON but did not carry a usable version.
Source
Thrown at gitnexus/src/core/update-check.ts:205
const location = response.headers.get('location');
await response.body?.cancel().catch(() => {});
if (!location) throw new Error('Registry redirect missing location');
url = sanitizedHttpUrl(location, url.toString());
continue;
}
if (!response.ok) {
await response.body?.cancel().catch(() => {});
throw new Error(`Registry returned ${response.status}`);
}
const parsed = JSON.parse(await readResponseBody(response)) as {
version?: unknown;
'dist-tags'?: { latest?: unknown };
};
const latest =
(typeof parsed.version === 'string' ? parsed.version : undefined) ??
(typeof parsed['dist-tags']?.latest === 'string' ? parsed['dist-tags'].latest : undefined);
if (typeof latest !== 'string' || !STRICT_UPDATE_VERSION.test(latest)) {
throw new Error('Registry latest version is invalid');
}
return latest;
}
}
async function publishMonotonically(
entry: UpdateCacheEntry,
attemptStartedAt: number,
): Promise<void> {
const current = await readCache(entry.registry);
const currentAt = current ? Date.parse(current.lastCheckAt) : Number.NaN;
// A later in-the-past write wins. Future-dated entries (wall-clock) are
// clock-skew poison and must stay replaceable so a later holder can repair them.
if (Number.isFinite(currentAt) && currentAt <= Date.now() && currentAt > attemptStartedAt) {
return;
}
await fs.mkdir(getGlobalDir(), { recursive: true });
await writeFileAtomic(cacheFile(), `${JSON.stringify(entry)}\n`, 1);View on GitHub (pinned to 0d1aed942f)
Solutions
- curl the endpoint and confirm the JSON contains version or dist-tags.latest with a valid semver string
- Point the update registry/package URL at the correct version/dist-tags document for the package
- Fix or replace the mirror so it serves npm-shaped version JSON
Example fix
// before (mirror returns {"ok":true})
// throws: Registry latest version is invalid
// after — correct endpoint returns:
// {"name":"gitnexus","version":"1.14.0","dist-tags":{"latest":"1.14.0"}} Defensive patterns
Strategy: type-guard
Validate before calling
const doc = await (await fetch(registryUrl)).json(); const ok = typeof doc?.version === 'string' && /^\d+\.\d+\.\d+/.test(doc.version) || typeof doc?.['dist-tags']?.latest === 'string'; if (!ok) skipUpdateCheck();
Type guard
function isValidVersionDoc(d: unknown): d is { version?: string; 'dist-tags'?: { latest?: string } } { const o = d as Record<string, unknown>; const v = o?.version ?? o?.['dist-tags']?.['latest']; return typeof v === 'string' && STRICT_UPDATE_VERSION.test(v); } Try / catch
try { const latest = await fetchLatest(url, 0); } catch (e) { if (e.message === 'Registry latest version is invalid') { console.warn('Registry served no valid version field; skipping update check'); } else throw e; } Prevention
- Only point update checks at endpoints returning npm-shaped version JSON
- Validate custom mirror response schemas against npm's before deploying
- Compare the endpoint's JSON output against the package on the canonical registry during setup
When it happens
Trigger: The endpoint returns JSON without a version/dist-tags.latest field (e.g. an error object like {"error":"not found"}, an empty object, or a HTML page that happens to parse); or the version string is malformed (pre-release tags the strict regex rejects, 'latest' as a literal, empty string).
Common situations: A custom mirror serving a different response schema than npm's; registry returning an error JSON with HTTP 200 (some proxies do); pointing the update URL at a generic endpoint instead of the package version document.
Related errors
- Unsupported npm registry protocol
- Registry URL cannot contain query or fragment
- Registry response too large
- Too many registry redirects
- Registry redirect missing location
AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-09-08).
Data as JSON: /api/errors/6045c74d2b4d75c6.
Report an issue: GitHub.