{"record":{"id":"e5623116965d244b","repo":"yarnpkg/yarn","slug":"malformedregistryresponse","errorCode":null,"errorMessage":"malformedRegistryResponse","messagePattern":"malformedRegistryResponse","errorType":"exception","errorClass":"MessageError","httpStatus":null,"severity":"error","filePath":"src/resolvers/registries/npm-resolver.js","lineNumber":44,"sourceCode":"  'dist-tags': {[key: string]: string},\n};\n\nexport default class NpmResolver extends RegistryResolver {\n  static registry = NPM_REGISTRY_ID;\n\n  static async findVersionInRegistryResponse(\n    config: Config,\n    name: string,\n    range: string,\n    body: RegistryResponse,\n    request: ?PackageRequest,\n  ): Promise<Manifest> {\n    if (body.versions && Object.keys(body.versions).length === 0) {\n      throw new MessageError(config.reporter.lang('registryNoVersions', body.name));\n    }\n\n    if (!body['dist-tags'] || !body.versions) {\n      throw new MessageError(config.reporter.lang('malformedRegistryResponse', name));\n    }\n\n    if (range in body['dist-tags']) {\n      range = body['dist-tags'][range];\n    }\n\n    // If the latest tag in the registry satisfies the requested range, then use that.\n    // Otherwise we will fall back to semver maxSatisfying.\n    // This mimics logic in NPM. See issue #3560\n    const latestVersion = body['dist-tags'] ? body['dist-tags'].latest : undefined;\n    if (latestVersion && semver.satisfies(latestVersion, range)) {\n      return body.versions[latestVersion];\n    }\n\n    const satisfied = await config.resolveConstraints(Object.keys(body.versions), range);\n    if (satisfied) {\n      return body.versions[satisfied];\n    } else if (request && !config.nonInteractive) {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/yarnpkg/yarn/blob/c2dda503f3759b5be5f0e24ecd9cf5c97a540147/src/resolvers/registries/npm-resolver.js#L26-L62","documentation":"findVersionInRegistryResponse() throws when body lacks dist-tags OR body lacks versions entirely. The registry response is structurally incomplete and cannot be used for resolution. This is distinct from error 93 which checks for an empty versions object.","triggerScenarios":"A registry returns JSON missing the dist-tags field or the versions field. Checked immediately after the empty-versions guard.","commonSituations":"Corrupt or non-compliant registry proxies; custom registries returning non-standard packuments; tarball-only or error endpoints that still return 200.","solutions":["Switch to the canonical npm registry to confirm the package exists there","Verify the registry endpoint returns the standard packument format (dist-tags + versions)","Check for proxy/CDN corruption altering the response body","Contact the registry provider if the format is non-standard"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function isWellFormedPackument(body: object): boolean {\n  return !!body['dist-tags'] && !!body.versions;\n}","typeGuard":"function isCompleteRegistryResponse(body: object): boolean {\n  return 'dist-tags' in body && 'versions' in body;\n}","tryCatchPattern":"try {\n  const manifest = await NpmResolver.findVersionInRegistryResponse(config, name, range, body);\n} catch (e) {\n  if (e.message.includes('malformedRegistryResponse')) {\n    // retry against the canonical npm registry\n  }\n}","preventionTips":["Use the canonical npm registry to confirm packument integrity","Avoid custom registries that return non-standard formats","Validate proxy responses for field completeness"],"tags":["registry","malformed","validation"],"backgroundTag":null,"analyzedSha":"c2dda503f3759b5be5f0e24ecd9cf5c97a540147","analyzedAt":"2026-08-13T04:17:06.305Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}