Skip to content

## Bug description #538

Description

@ifteneiftene

Bug description

When saving any file inside snippets/ during mint dev, the terminal fills with MDX parsing errors from files inside node_modules. Despite node_modules being listed in DEFAULT_MINT_IGNORES and in .mintignore, the errors still appear on every file save.

Steps to reproduce

  1. Create a Mintlify project with node_modules present (standard setup)
  2. Add any .jsx file to snippets/, e.g. snippets/MyComponent.jsx
  3. Run mint dev
  4. Save snippets/MyComponent.jsx
  5. Observe parsing errors for files in node_modules printed to the terminal

Expected behavior

No errors from node_modules — those files should be ignored, as documented in .mintignore and DEFAULT_MINT_IGNORES.

Actual behavior

On every save of a snippet file, dozens of errors like:

parsing error ./node_modules/.pnpm/@biomejs+biome@2.4.3/node_modules/@biomejs/biome/README.es.md:28:2 - Unexpected character `!` (U+0021) before name, expected a character that can start a name, such as a letter, `$`, or `_` (note: to create a comment in MDX, use `{/* text */}`)
parsing error ./node_modules/.pnpm/acorn@8.15.0/node_modules/acorn/CHANGELOG.md:49:71 - Unexpected character `8` ...

Root cause

The issue is in @mintlify/previewing. Several functions use getFileListSync from @mintlify/prebuild, which recursively scans all files without applying any ignore patterns.

packages/previewing/src/local-preview/listener/generatePagesWithImports.ts (triggered on every snippet save):

const pageFilenames = getFileListSync(CMD_EXEC_PATH).filter((file) => {
  if (!isSnippetExtension(getFileExtension(file))) return false;
  const category = getFileCategory(file, { importedFiles });
  return category === 'page'; // ← node_modules/*.md files pass this check
});

getFileListSync has no awareness of .mintignore or DEFAULT_MINT_IGNORES:

// @mintlify/prebuild - fs/index.ts
export const getFileListSync = (dirName: string, og = dirName): string[] => {
  const files: string[] = [];
  const items = readdirSync(dirName, { withFileTypes: true });
  for (const item of items) {
    const fullPath = path.join(dirName, item.name);
    if (item.isDirectory()) {
      files.push(...getFileListSync(fullPath, og)); // ← recurses into node_modules
    } else {
      files.push(toPosixPath(path.relative(og, fullPath)));
    }
  }
  return files;
};

By contrast, the async getFileList correctly applies isMintIgnored:

export async function* getFileList(dirName, og = dirName, mintIgnore = []) {
  const items = await readdir(dirName, { withFileTypes: true });
  for (const item of items) {
    const relativePath = toPosixPath(path.relative(og, fullPath));
    if (isMintIgnored(relativePath, mintIgnore)) continue; // ✅ filters node_modules
    // ...
  }
}

The same issue exists in getSnippets.ts and importCache.ts (fallback path).

Suggested fix

getFileListSync should accept an optional mintIgnore parameter and apply isMintIgnored, mirroring the async getFileList:

export const getFileListSync = (
  dirName: string,
  og = dirName,
  mintIgnore: string[] = []
): string[] => {
  const files: string[] = [];
  const items = readdirSync(dirName, { withFileTypes: true });
  for (const item of items) {
    const fullPath = path.join(dirName, item.name);
    const relativePath = toPosixPath(path.relative(og, fullPath));
    if (isMintIgnored(relativePath, mintIgnore)) continue; // ← add this
    if (item.isDirectory()) {
      files.push(...getFileListSync(fullPath, og, mintIgnore));
    } else {
      files.push(relativePath);
    }
  }
  return files;
};

All callers (generatePagesWithImports, getSnippets, importCache) would then need to pass the result of getMintIgnoreGlobs().

Environment

  • mint version: 4.2.367
  • Package manager: pnpm (with .pnpm virtual store layout)

Originally posted by @equinusocio in mintlify/docs#3577

Originally posted by @ifteneiftene in mintlify/docs#3680

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions