parcel-bundler/parcel · error · ThrowableDiagnostic

${path.relative(process.cwd(), source)} does not exist.

Error message

${path.relative(process.cwd(), source)} does not exist.

What it means

Thrown by assertFile() when fs.stat(source) rejects — the file path referenced by the source field in package.json (or a target's source) does not exist on disk. Parcel produces a ThrowableDiagnostic with a code frame pointing at the offending value in package.json and suggests likely alternative filenames.

Source

Thrown at packages/core/core/src/requests/EntryRequest.js:109

  relativeSource: FilePath,
  pkgFilePath: FilePath,
  keyPath: string,
  options: ParcelOptions,
) {
  let source = path.join(entry, relativeSource);
  let stat;
  try {
    stat = await fs.stat(source);
  } catch (err) {
    let contents = await fs.readFile(pkgFilePath, 'utf8');
    let alternatives = await findAlternativeFiles(
      fs,
      relativeSource,
      entry,
      options.projectRoot,
      false,
    );
    throw new ThrowableDiagnostic({
      diagnostic: {
        origin: '@parcel/core',
        message: md`${path.relative(process.cwd(), source)} does not exist.`,
        codeFrames: [
          {
            filePath: pkgFilePath,
            codeHighlights: generateJSONCodeHighlights(contents, [
              {
                key: keyPath,
                type: 'value',
              },
            ]),
          },
        ],
        hints: alternatives.map(r => {
          return md`Did you mean '__${r}__'?`;
        }),
      },

View on GitHub (pinned to 59484858a1)

Solutions

  1. Check the file path in package.json source / targets.*.source — verify it exists with ls.
  2. If you renamed the file, update the source field to match the new name.
  3. If on Linux, verify the casing matches exactly (e.g., Index.js vs index.js).
  4. Use the 'Did you mean' hint in the diagnostic to pick the correct filename.
  5. If the path is intentional but not yet created, create the file or switch to a glob pattern.

Example fix

// before — package.json
{
  "source": "src/inde.html"
}

// after
{
  "source": "src/index.html"
}
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
const path = require('path');
function validatePackageSource(pkgPath) {
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
  const sources = Array.isArray(pkg.source) ? pkg.source : pkg.source ? [pkg.source] : [];
  for (const s of sources) {
    const full = path.join(path.dirname(pkgPath), s);
    if (!fs.existsSync(full)) {
      throw new Error(`Source file not found: ${full} (from package.json "source": "${s}")`);
    }
  }
}

Prevention

When it happens

Trigger: Called from resolveEntry() while validating each relativeSource from pkg.source (or pkg.targets[*].source). The joined path path.join(entry, relativeSource) fails stat(). This fires for non-glob source strings; globs are expanded separately.

Common situations: Renaming or moving an entry file without updating package.json source; typo in the source path; case-sensitivity mismatch on Linux after committing from macOS/Windows; deleting the entry file but leaving package.json pointing at it; source field pointing to a file in a subdirectory that was never created.

Related errors


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