{"record":{"id":"12b3da919ec24743","repo":"expo/expo","slug":"the-prebuilt-metadata-catalog-requires-an-expo-rep","errorCode":null,"errorMessage":"The prebuilt-metadata catalog requires an expo repository checkout. Use the app-plan mode for standalone projects.","messagePattern":"The prebuilt-metadata catalog requires an expo repository checkout\\. Use the app-plan mode for standalone projects\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/expo-modules-autolinking/src/prebuiltMetadata.ts","lineNumber":83,"sourceCode":"        .map((podName) => [podName, entries[podName]!])\n    );\n  });\n}\n\n/** The expo repository root when this package runs from its packages/ checkout\n * (its own location is the same anchor used for external-configs below). */\nfunction findExpoRepoRoot(): string | null {\n  const repoRoot = path.resolve(__dirname, '..', '..', '..');\n  return fs.existsSync(path.join(repoRoot, 'packages', 'expo-modules-core', 'spm.config.json'))\n    ? repoRoot\n    : null;\n}\n\n/** Every package in the expo repository, whether or not an app depends on it. */\nasync function scanRepoPackagesAsync(): Promise<DiscoveredPackages> {\n  const repoRoot = findExpoRepoRoot();\n  if (!repoRoot) {\n    throw new Error(\n      'The prebuilt-metadata catalog requires an expo repository checkout. Use the app-plan mode for standalone projects.'\n    );\n  }\n  return scanDependenciesInSearchPath(path.join(repoRoot, 'packages'));\n}\n\n/** Only the packages the app itself resolves. */\nasync function findAppPackagesAsync(\n  appRoot: string,\n  optionsLoader: LinkingOptionsLoader\n): Promise<DiscoveredPackages> {\n  return findModulesAsync({\n    appRoot,\n    autolinkingOptions: await optionsLoader.getPlatformOptions('apple'),\n  });\n}\n\nfunction readJsonFile(filePath: string): any | null {","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/expo/expo/blob/7da61120be99bcd9cc2e5dbdba6d803c21b5c68b/packages/expo-modules-autolinking/src/prebuiltMetadata.ts#L65-L101","documentation":"expo-modules-autolinking's prebuilt-metadata catalog has a repo-scanning mode (scanRepoPackagesAsync) that only works inside the expo/expo monorepo, because it scans <repoRoot>/packages. When findExpoRepoRoot() cannot locate an expo checkout above the working directory, it throws and tells you to use the app-plan mode instead.","triggerScenarios":"Invoking the prebuilt-metadata resolution (e.g. `packages` in repo-scan mode) from a standalone React Native project, a fork without the repo marker files, or from a directory outside any expo/expo clone.","commonSituations":"Running expo-modules-autolinking tooling from an app project that vendors only some packages; CI checkout of a single package without the monorepo; a shallow/partial clone that dropped the root marker files findExpoRepoRoot() looks for.","solutions":["Switch to the app-plan (dependency-based) resolution mode instead of the repo-scan/prebuilt-metadata mode for standalone projects.","Run the tooling from inside a full expo/expo checkout so findExpoRepoRoot() finds the repository root.","If in a fork, restore the monorepo root files (package.json/workspaces config) that identify the expo repo.","Clone the full expo monorepo and run the metadata scan from its root."],"exampleFix":"// before (standalone app repo)\nconst pkgs = await scanRepoPackagesAsync();\n\n// after\nconst pkgs = await resolveAppPlanPackagesAsync(projectRoot); // app-plan mode","handlingStrategy":"fallback","validationCode":"const fs = require('fs');\nfunction isInExpoRepo(root = process.cwd()) {\n  return fs.existsSync(`${root}/packages/expo/package.json`) ||\n         fs.existsSync(`${root}/packages`);\n}","typeGuard":null,"tryCatchPattern":"let packages;\ntry {\n  packages = await resolvePrebuiltMetadata();\n} catch (e) {\n  if (String(e.message).includes('requires an expo repository checkout')) {\n    packages = await resolveAppPlanPackagesAsync(projectRoot); // fallback mode\n  } else throw e;\n}","preventionTips":["Run monorepo-only tooling from inside a full expo/expo checkout.","Prefer the app-plan resolution mode for standalone app projects.","Avoid shallow/partial clones when repo-scanning tooling will run."],"tags":["autolinking","monorepo","configuration","expo-modules"],"backgroundTag":"missing-env-var","analyzedSha":"7da61120be99bcd9cc2e5dbdba6d803c21b5c68b","analyzedAt":"2026-09-09T16:01:44.845Z","contentChangedAt":"2026-09-09T16:01:44.845Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}