yarnpkg/yarn · error · Error
Unexpected audit response (Invalid JSON): ${response}
Error message
Unexpected audit response (Invalid JSON): ${response} What it means
The audit command POSTs the dependency bundle (gzipped JSON) to the registry audit endpoint, then `JSON.parse(response)` is wrapped in try/catch at `audit.js:258`. If the body is not valid JSON the catch rethrows this error with the raw response inlined. It indicates the endpoint returned HTML, plain text, an error page, or an empty body rather than the expected JSON document.
Source
Thrown at src/cli/commands/audit.js:258
let responseJson;
const registry = YARN_REGISTRY;
this.reporter.verbose(`Audit Request: ${JSON.stringify(auditTree, null, 2)}`);
const requestBody = await gzip(JSON.stringify(auditTree));
const response = await this.config.requestManager.request({
url: `${registry}/-/npm/v1/security/audits`,
method: 'POST',
body: requestBody,
headers: {
'Content-Encoding': 'gzip',
'Content-Type': 'application/json',
Accept: 'application/json',
},
});
try {
responseJson = JSON.parse(response);
} catch (ex) {
throw new Error(`Unexpected audit response (Invalid JSON): ${response}`);
}
if (!responseJson.metadata) {
throw new Error(`Unexpected audit response (Missing Metadata): ${JSON.stringify(responseJson, null, 2)}`);
}
this.reporter.verbose(`Audit Response: ${JSON.stringify(responseJson, null, 2)}`);
return responseJson;
}
_insertWorkspacePackagesIntoManifest(manifest: Object, resolver: PackageResolver) {
if (resolver.workspaceLayout) {
const workspaceAggregatorName = resolver.workspaceLayout.virtualManifestName;
const workspaceManifest = resolver.workspaceLayout.workspaces[workspaceAggregatorName].manifest;
manifest.dependencies = Object.assign(manifest.dependencies || {}, workspaceManifest.dependencies);
manifest.devDependencies = Object.assign(manifest.devDependencies || {}, workspaceManifest.devDependencies);
manifest.optionalDependencies = Object.assign(
manifest.optionalDependencies || {},
workspaceManifest.optionalDependencies,View on GitHub (pinned to c2dda503f3)
Solutions
- Check `yarn config get registry` and point it at a registry that supports audit (official `https://registry.yarnpkg.com`).
- Retry; transient outages or proxy hiccups often resolve.
- If behind a proxy, verify `HTTP_PROXY`/`HTTPS_PROXY` and that it permits the audit POST.
- Run `curl -v <registry>/-/npm/v1/security/audit` to inspect the raw body returned.
Example fix
// before $ yarn audit // registry returns HTML login page // after $ yarn config set registry https://registry.yarnpkg.com $ yarn audit
Defensive patterns
Strategy: retry
Validate before calling
// Probe the audit endpoint shape before delegating to yarn audit
async function auditEndpointOk(registry: string): Promise<boolean> {
try {
const res = await fetch(`${registry}/-/npm/v1/security/audit`, { method: 'POST', body: '{}' });
const txt = await res.text();
try { JSON.parse(txt); return true; } catch { return false; }
} catch { return false; }
} Type guard
function looksLikeJson(s: string): boolean {
const t = s.trim();
return (t.startsWith('{') || t.startsWith('[')) && t.length > 0;
} Try / catch
async function auditWithRetry(runAudit, attempts = 3) {
for (let i = 0; i < attempts; i++) {
try { return await runAudit(); }
catch (e) {
if (/Invalid JSON/.test(e.message) && i < attempts - 1) {
await new Promise(r => setTimeout(r, 500 * (i + 1)));
continue;
}
throw e;
}
}
} Prevention
- Pin `registry` to a known-good value in CI rather than relying on ambient config.
- Verify proxy egress for the audit POST endpoint.
- Treat 'Invalid JSON' as transient first — retry before escalating.
When it happens
Trigger: `JSON.parse(response)` throws inside the audit handler — the registry/audit endpoint returned a non-JSON body. Common with corporate proxies, captive portals, misconfigured `registry` in `.yarnrc`, or registry outages.
Common situations: Custom/private registry that does not implement the npm audit HTTP API, a transparent proxy injecting an HTML login page, an air-gapped network, or `https-proxy-agent` returning a proxy error page.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unexpected audit response (Missing Metadata): ${JSON.stringi
- publishFail
- packageNotFoundRegistry
- Couldn't find package $0 required by $1 on the $2 registry.
- couldn't find ${name}
AI-assisted analysis of yarnpkg/yarn@c2dda503f3 (2026-08-13).
Data as JSON: /api/errors/35bc36a9d9747980.
Report an issue: GitHub.