parcel-bundler/parcel · error · ThrowableDiagnostic

Cannot find extended parcel config

Error message

Cannot find extended parcel config

What it means

Thrown by resolveExtends() when a non-relative extends specifier (not starting with '.') cannot be resolved as a Node module via packageManager.resolve(). The diagnostic shows the extends value in the parent config and suggests alternative module names using findAlternativeNodeModules.

Source

Thrown at packages/core/core/src/requests/ParcelConfigRequest.js:500

  ext: string,
  configPath: FilePath,
  extendsKey: string,
  options: ParcelOptions,
): Promise<FilePath> {
  if (ext.startsWith('.')) {
    return path.resolve(path.dirname(configPath), ext);
  } else {
    try {
      let {resolved} = await options.packageManager.resolve(ext, configPath);
      return options.inputFS.realpath(resolved);
    } catch (err) {
      let parentContents = await options.inputFS.readFile(configPath, 'utf8');
      let alternatives = await findAlternativeNodeModules(
        options.inputFS,
        ext,
        path.dirname(configPath),
      );
      throw new ThrowableDiagnostic({
        diagnostic: {
          message: `Cannot find extended parcel config`,
          origin: '@parcel/core',
          codeFrames: [
            {
              filePath: configPath,
              language: 'json5',
              code: parentContents,
              codeHighlights: generateJSONCodeHighlights(parentContents, [
                {
                  key: extendsKey,
                  type: 'value',
                  message: md`Cannot find module "${ext}"${
                    alternatives[0]
                      ? `, did you mean "${alternatives[0]}"?`
                      : ''
                  }`,
                },

View on GitHub (pinned to 59484858a1)

Solutions

  1. Install the missing config package: npm install --save-dev <package-name>.
  2. Check the 'did you mean' suggestion in the diagnostic for the correct name.
  3. Verify the exact package name on npm: npm view <package-name>.
  4. If the package was renamed, update the extends field to the new name.
  5. For scoped packages, ensure the @scope/ prefix is included.

Example fix

// before — .parcelrc
{
  "extends": "@parcel/config-defalt"
}

// after
{
  "extends": "@parcel/config-default"
}
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
function validateExtendsPackageExists(parcelrcPath) {
  const cfg = JSON.parse(fs.readFileSync(parcelrcPath, 'utf8'));
  const extendsList = Array.isArray(cfg.extends) ? cfg.extends : cfg.extends ? [cfg.extends] : [];
  for (const ext of extendsList) {
    if (typeof ext === 'string' && !ext.startsWith('.')) {
      try {
        require.resolve(ext, { paths: [require('path').dirname(parcelrcPath)] });
      } catch {
        throw new Error(`Extends package "${ext}" is not installed. Run: npm install --save-dev ${ext}`);
      }
    }
  }
}

Prevention

When it happens

Trigger: resolveExtends() is called for each entry in the extends array of .parcelrc. If the specifier doesn't start with '.', it's treated as a package name and resolved. When resolve() throws (module not found), the catch block builds a diagnostic with 'Cannot find module' and did-you-mean suggestions.

Common situations: Typo in the extends package name; package not installed (forgot npm install); package name changed after an upgrade; scoped package with missing @scope prefix; extends references a config that was renamed or deprecated.

Related errors


AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13). Data as JSON: /api/errors/361603bbec92ce42. Report an issue: GitHub.