{"record":{"id":"31181f609057b11b","repo":"yarnpkg/yarn","slug":"invalidfragment","errorCode":null,"errorMessage":"invalidFragment","messagePattern":"invalidFragment","errorType":"validation","errorClass":"MessageError","httpStatus":null,"severity":"error","filePath":"src/resolvers/exotics/registry-resolver.js","lineNumber":17,"sourceCode":"/* @flow */\n\nimport type {Manifest} from '../../types.js';\nimport type PackageRequest from '../../package-request.js';\nimport {MessageError} from '../../errors.js';\nimport ExoticResolver from './exotic-resolver.js';\n\nexport default class RegistryResolver extends ExoticResolver {\n  constructor(request: PackageRequest, fragment: string) {\n    super(request, fragment);\n\n    const match = fragment.match(/^(\\S+):(@?.*?)(@(.*?)|)$/);\n    if (match) {\n      this.range = match[4] || 'latest';\n      this.name = match[2];\n    } else {\n      throw new MessageError(this.reporter.lang('invalidFragment', fragment));\n    }\n\n    // $FlowFixMe\n    this.registry = this.constructor.protocol;\n  }\n\n  static factory: Function;\n  name: string;\n  range: string;\n\n  resolve(): Promise<Manifest> {\n    return this.fork(this.constructor.factory, false, this.name, this.range);\n  }\n}\n","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/yarnpkg/yarn/blob/c2dda503f3759b5be5f0e24ecd9cf5c97a540147/src/resolvers/exotics/registry-resolver.js#L1-L32","documentation":"RegistryResolver's constructor tests the fragment against /^ (\\S+):(@?.*?)(@(.*?)|)$/. If no match, the fragment does not conform to the <protocol>:<name>@<range> exotic format and is rejected at construction time.","triggerScenarios":"An exotic resolver fragment (e.g., an npm: alias) that fails the protocol/name/range regex. Constructor-time validation before resolution begins.","commonSituations":"Malformed npm: alias dependencies; missing protocol prefix; illegal whitespace or characters in the fragment.","solutions":["Format exotic dependencies as <protocol>:<name>@<range>","For npm aliases, use the exact form npm:<real-name>@<semver-range>","Remove whitespace or illegal characters from the fragment"],"exampleFix":"// before\n\"aliased\": \"npm-real-pkg@^1.0.0\"\n// after\n\"aliased\": \"npm:npm-real-pkg@^1.0.0\"","handlingStrategy":"validation","validationCode":"function isValidExoticFragment(fragment: string): boolean {\n  return /^(\\S+):(@?.*?)(@(.*?)|)$/.test(fragment);\n}","typeGuard":"function isWellFormedRegistryFragment(fragment: string): boolean {\n  return /^(\\S+):(@?.*?)(@(.*?)|)$/.test(fragment);\n}","tryCatchPattern":null,"preventionTips":["Format npm: aliases as npm:<name>@<range>","Include the protocol prefix for all exotic dependencies","Test exotic fragments against the constructor regex before committing"],"tags":["exotic-resolver","fragment","registry"],"backgroundTag":null,"analyzedSha":"c2dda503f3759b5be5f0e24ecd9cf5c97a540147","analyzedAt":"2026-08-13T04:17:06.305Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}