{"record":{"id":"144fcf5dfcbd06eb","repo":"gatsbyjs/gatsby","slug":"failed-to-resolve-themename","errorCode":null,"errorMessage":"Failed to resolve ${themeName}","messagePattern":"Failed to resolve (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/gatsby/src/bootstrap/load-themes/index.ts","lineNumber":57,"sourceCode":"    const scopedRequire = createRequireFromPath(`${rootDir}/:internal:`)\n    // theme is an node-resolvable module\n    themeDir = path.dirname(scopedRequire.resolve(themeName))\n  } catch (e) {\n    let pathToLocalTheme\n\n    // only try to look for local theme in main site\n    // local themes nested in other themes is potential source of problems:\n    // because those are not hosted by npm, there is potential for multiple\n    // local themes with same name that do different things and name being\n    // main identifier that Gatsby uses right now, it's safer not to support it for now.\n    if (isMainConfig) {\n      pathToLocalTheme = path.join(rootDir, `plugins`, themeName)\n      // is a local plugin OR it doesn't exist\n      try {\n        const { resolve } = resolvePlugin(themeName, rootDir)\n        themeDir = resolve\n      } catch (localErr) {\n        reporter.panic(`Failed to resolve ${themeName}`, localErr)\n      }\n    }\n\n    if (!themeDir) {\n      const nodeResolutionPaths = module.paths.map(p => path.join(p, themeName))\n      reporter.panic({\n        id: `10226`,\n        context: {\n          themeName,\n          configFilePath: configFileThatDeclaredTheme,\n          pathToLocalTheme,\n          nodeResolutionPaths,\n        },\n      })\n    }\n  }\n\n  const { configModule, configFilePath } = await getConfigFile(","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby/src/bootstrap/load-themes/index.ts#L39-L75","documentation":"Thrown by Gatsby's theme loader when resolving a theme that is not the main config fails locally. The loader first tries a local theme at <rootDir>/plugins/<themeName> via resolvePlugin; if that throws (the local plugin is invalid or missing required files), it immediately panics with the caught localErr attached. This is the 'local theme exists but is broken' branch, distinct from the 'cannot find theme at all' branch that follows.","triggerScenarios":"A theme listed in gatsby-config.js resolves to plugins/<themeName> on disk, but resolvePlugin throws because gatsby-node.js/gatsby-config.js is missing, package.json is malformed, or the plugin does not satisfy the local plugin contract.","commonSituations":"Renaming a theme directory without updating gatsby-config.js; a local theme missing its index or gatsby-node entry; a local theme whose package.json 'main' points to a non-existent file; symlinking a theme whose dependencies are not installed.","solutions":["Open the localErr object printed with the panic: it carries the specific reason resolvePlugin failed.","Verify plugins/<themeName>/ has a valid package.json (with a correct 'main' or 'name') and a gatsby-node.js or gatsby-config.js if the theme uses them.","Run npm/yarn install inside the local theme directory to ensure its own dependencies are present.","If the theme is meant to come from npm, remove the local plugins/<themeName> directory so node resolution applies."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before starting Gatsby, sanity-check local themes resolve:\nconst path = require('path'), fs = require('fs')\nfor (const theme of (config.plugins || [])) {\n  const name = typeof theme === 'string' ? theme : theme.resolve\n  const local = path.join(process.cwd(), 'plugins', name)\n  if (fs.existsSync(local)) {\n    const pkg = path.join(local, 'package.json')\n    if (!fs.existsSync(pkg)) console.warn(`Local theme ${name} missing package.json`)\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep local theme directories self-contained: package.json + entry file.","Run install inside local theme directories.","Remove empty plugins/<name> directories when the theme is expected from npm.","Use the localErr object printed with the panic to find the precise resolution failure."],"tags":["themes","plugins","config","resolution"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}