{"record":{"id":"17aba74be7fe5132","repo":"mui/material-ui","slug":"could-not-find-version-in-versions","errorCode":null,"errorMessage":"Could not find '${version}' in \"${versions}\"","messagePattern":"Could not find '(.+?)' in \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/useReactVersion.mjs","lineNumber":70,"sourceCode":"      const tagMapping = versions.split('\\n').find((mapping) => {\n        return mapping.startsWith(`${version}: `);\n      });\n\n      let packageVersion = null;\n\n      if (tagMapping === undefined) {\n        // Some specific version is being requested\n        if (majorVersion) {\n          packageVersion = version;\n          if (reactPackageName === 'scheduler') {\n            // get the scheduler version from the react-dom's dependencies entry\n            const { stdout: reactDOMDependenciesString } = await exec(\n              `npm view --json react-dom@${version} dependencies`,\n            );\n            packageVersion = JSON.parse(reactDOMDependenciesString).scheduler;\n          }\n        } else {\n          throw new Error(`Could not find '${version}' in \"${versions}\"`);\n        }\n      } else {\n        packageVersion = tagMapping.replace(`${version}: `, '');\n      }\n\n      packageJson.resolutions[reactPackageName] = packageVersion;\n    }),\n  );\n\n  // At this moment all dist tags reference React 18 version, so we don't need\n  // to update these dependencies unless an older version is used, or when the\n  // next/experimental dist tag reference to a future version of React\n  // packageJson.devDependencies['@testing-library/react'] = 'alpha';\n\n  if (majorVersion && additionalVersionsMappings[majorVersion]) {\n    devDependenciesPackageNames.forEach((packageName) => {\n      if (!additionalVersionsMappings[majorVersion][packageName]) {\n        throw new Error(","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/mui/material-ui/blob/bdc96df2cb530fcdd60a7a7aabe37f610ce0f0a5/scripts/useReactVersion.mjs#L52-L88","documentation":"Thrown when the requested `version` is treated as a dist-tag name but `npm dist-tag ls <pkg>` produced no line beginning with `${version}: `, AND the version string did not look like a concrete semver (it did not start with `^`, `~`, or a digit, so majorVersion stayed null). The check runs inside the reactPackageNames.map loop, so it fires on the first React package whose tag list lacks the entry — typically `react` itself.","triggerScenarios":"Passing a tag name that does not exist on the npm registry for the React packages, e.g. `node scripts/useReactVersion.mjs rc` when there is no `rc` dist-tag. Also fires for arbitrary non-version strings (`latest2`, `foobar`) because they neither match a dist-tag nor parse as a semver.","commonSituations":"Typo in the tag name (`next` vs `nex`); the React maintainers renamed or removed a dist-tag; querying against a private registry mirror that does not propagate dist-tags; using a tag name that only some sub-packages publish.","solutions":["List the real tags with `npm dist-tag ls react` and pass one of those names.","If you want a concrete release instead of a tag, pass a real version (`18.2.0`) or range (`^18`) — those go through the majorVersion branch and skip this throw.","Check registry connectivity and config (`npm config get registry`, `npm ping`) if the tag list comes back empty."],"exampleFix":"// before\n$ node scripts/useReactVersion.mjs nex\n# Error: Could not find 'nex' in \"\"\n\n// after\n$ node scripts/useReactVersion.mjs next\n# (script proceeds to rewrite resolutions and run pnpm install)","handlingStrategy":"validation","validationCode":"// Pre-flight: confirm the requested tag exists on npm for every React\n// package the script will iterate, so the dist-tag ls loop never throws.\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\nconst execAsync = promisify(exec);\n\nconst reactPackages = ['react', 'react-dom', 'react-is', 'scheduler'];\n\nasync function assertTagExists(tag: string) {\n  if (/^[~^]/.test(tag) || /^\\d/.test(tag)) return; // concrete version/range, not a tag\n  for (const pkg of reactPackages) {\n    const { stdout } = await execAsync(`npm dist-tag ls ${pkg}`);\n    if (!stdout.split('\\n').some((line) => line.startsWith(`${tag}: `))) {\n      throw new Error(`dist-tag \"${tag}\" not found for ${pkg}. Available:\\n${stdout}`);\n    }\n  }\n}","typeGuard":"// Narrows a candidate to a known dist-tag name given an npm tag listing.\nfunction isKnownDistTag(\n  tag: string,\n  listing: string,\n): tag is string {\n  return listing.split('\\n').some((line) => line.startsWith(`${tag}: `));\n}","tryCatchPattern":"// Distinguish a tag-not-found error from other failures so callers can\n// suggest the list of available tags.\ntry {\n  await main(version);\n} catch (err) {\n  if (err instanceof Error && /Could not find/.test(err.message)) {\n    const { stdout } = await execAsync('npm dist-tag ls react');\n    throw new Error(`Unknown tag \"${version}\". Available react dist-tags:\\n${stdout}`);\n  }\n  throw err;\n}","preventionTips":["Before introducing a new tag value into CI, run `npm dist-tag ls react` and copy the exact name.","Prefer concrete versions (`18.2.0`) over tags when reproducibility matters — they bypass the dist-tag lookup entirely.","Pin the registry with `npm config set registry` in mirrored environments so dist-tags are not silently empty.","Add a wrapper that, on this specific error, prints the available tags for `react` so the next attempt is correct."],"tags":["npm","dist-tag","react","registry","argument-validation"],"backgroundTag":null,"analyzedSha":"bdc96df2cb530fcdd60a7a7aabe37f610ce0f0a5","analyzedAt":"2026-08-12T22:59:56.717Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}