parcel-bundler/parcel · error · ThrowableDiagnostic

Invalid distPath for target "${targetName}"

Error message

Invalid distPath for target "${targetName}"

What it means

Each target needs a string `distDir` (output directory). When the resolved `distPath` is present but not a string (e.g. a number, object, or array was provided for the target field), TargetRequest throws `Invalid distPath for target "<name>"`. The highlight points at `/<targetName>` in package.json.

Source

Thrown at packages/core/core/src/requests/TargetRequest.js:1009

          distDir = path.join(distDir, targetName);
        }
        invariant(pkgMap != null);
        invariant(typeof pkgFilePath === 'string');
        loc = {
          filePath: pkgFilePath,
          ...getJSONSourceLocation(
            pkgMap.pointers[`/targets/${targetName}`],
            'key',
          ),
        };
      } else {
        if (typeof distPath !== 'string') {
          let contents: string =
            typeof pkgContents === 'string'
              ? pkgContents
              : // $FlowFixMe
                JSON.stringify(pkgContents, null, '\t');
          throw new ThrowableDiagnostic({
            diagnostic: {
              message: md`Invalid distPath for target "${targetName}"`,
              origin: '@parcel/core',
              codeFrames: [
                {
                  language: 'json',
                  filePath: pkgFilePath ?? undefined,
                  code: contents,
                  codeHighlights: generateJSONCodeHighlights(contents, [
                    {
                      key: `/${targetName}`,
                      type: 'value',
                      message: 'Expected type string',
                    },
                  ]),
                },
              ],
            },

View on GitHub (pinned to 59484858a1)

Solutions

  1. Set the target field to a string output file path, e.g. `"main": "dist/index.js"`.
  2. If using the `targets` object form, ensure each target's `distDir`/`source` values are strings.
  3. Validate package.json with a JSON schema linter for Parcel target fields.

Example fix

// before (package.json)
{
  "main": ["dist/index.js"]
}

// after
{
  "main": "dist/index.js"
}
Defensive patterns

Strategy: type-guard

Validate before calling

function assertTargetDistPath(pkg) {
  for (const [name, value] of Object.entries(pkg.targets || {})) {
    if (value?.distDir != null && typeof value.distDir !== 'string') {
      throw new Error(`targets.${name}.distDir must be a string`);
    }
  }
  for (const f of ['main','module','browser','types']) {
    if (f in pkg && typeof pkg[f] !== 'string') {
      throw new Error(`Field ${f} must be a string path`);
    }
  }
}

Type guard

function isStringDistPath(v) {
  return v == null || typeof v === 'string';
}

Try / catch

try { await parcel.run(); } catch (e) {
  if (/Invalid distPath for target/.test(e.message)) {
    console.error('Ensure target dist path fields are strings.');
  } else throw e;
}

Prevention

When it happens

Trigger: Providing a non-string value for a target's dist path in package.json, e.g. `"main": 123` or `"main": ["a.js","b.js"]` in a context where a single string path is required.

Common situations: JSON typo where a target field is set to a number/array/object; tooling that auto-generates package.json with malformed target values; mixing the legacy `main: string` API with the `targets` object form incorrectly.

Related errors


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