parcel-bundler/parcel · error · ThrowableDiagnostic

Missing distDir for target "${name}"

Error message

Missing distDir for target "${name}"

What it means

Thrown by TargetRequest.resolve() when targets are passed as an object map (not an array) and a target descriptor is missing the required distDir property. distDir specifies the output directory for that target and is mandatory for object-form targets. A code frame highlights the offending target in the serialized options.

Source

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

          .filter(Boolean);
      } else {
        // Otherwise, it's an object map of target descriptors (similar to those
        // in package.json). Adapt them to native targets.
        targets = Object.entries(optionTargets)
          .map(([name, _descriptor]) => {
            let {distDir, ...descriptor} = parseDescriptor(
              name,
              _descriptor,
              null,
              JSON.stringify({targets: optionTargets}, null, '\t'),
            );
            if (distDir == null) {
              let optionTargetsString = JSON.stringify(
                optionTargets,
                null,
                '\t',
              );
              throw new ThrowableDiagnostic({
                diagnostic: {
                  message: md`Missing distDir for target "${name}"`,
                  origin: '@parcel/core',
                  codeFrames: [
                    {
                      code: optionTargetsString,
                      codeHighlights: generateJSONCodeHighlights(
                        optionTargetsString || '',
                        [
                          {
                            key: `/${name}`,
                            type: 'value',
                          },
                        ],
                      ),
                    },
                  ],
                },

View on GitHub (pinned to 59484858a1)

Solutions

  1. Add a distDir property to the target descriptor in the options object.
  2. If you want the default output directory, set distDir to 'dist' explicitly.
  3. Verify every target in the object map has distDir — the code frame shows which one is missing.
  4. Consider using package.json targets instead, where distDir can be inferred from the target name.

Example fix

// before
const bundler = new Parcel({
  entries: 'src/index.html',
  targets: {
    app: {
      context: 'browser',
      outputFormat: 'esmodule'
      // distDir missing
    }
  }
});

// after
const bundler = new Parcel({
  entries: 'src/index.html',
  targets: {
    app: {
      distDir: 'dist',
      context: 'browser',
      outputFormat: 'esmodule'
    }
  }
});
Defensive patterns

Strategy: validation

Validate before calling

function validateObjectTargetsHaveDistDir(targets) {
  if (targets == null || Array.isArray(targets)) return;
  for (const [name, descriptor] of Object.entries(targets)) {
    if (descriptor.distDir == null) {
      throw new Error(`Target "${name}" is missing required "distDir" property.`);
    }
  }
}

Type guard

function hasAllDistDirs(targets) {
  if (targets == null || Array.isArray(targets)) return true;
  return Object.entries(targets).every(([, d]) => d != null && typeof d.distDir === 'string' && d.distDir.length > 0);
}

Prevention

When it happens

Trigger: In the Object.entries(optionTargets).map() branch, parseDescriptor extracts distDir from the descriptor. If distDir == null (absent or explicitly null), the error fires with a JSON code frame showing the target's value in the option targets string.

Common situations: Passing targets as an object programmatically and forgetting distDir; copy-pasting a target descriptor from package.json (which can infer distDir) into the API (which cannot); assuming distDir defaults to 'dist' — it does not for object-form targets.

Related errors


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