Skip to content

fix(dev): skip temporary files in content watcher to prevent crashes#3784

Open
surohak wants to merge 1 commit intonuxt:mainfrom
surohak:fix/ignore-temp-files-in-watcher
Open

fix(dev): skip temporary files in content watcher to prevent crashes#3784
surohak wants to merge 1 commit intonuxt:mainfrom
surohak:fix/ignore-temp-files-in-watcher

Conversation

@surohak
Copy link
Copy Markdown

@surohak surohak commented May 6, 2026

Description

Editors and AI tools that use non-atomic writes create intermediate files like example.md.tmp.153372 in content directories. The content watcher picks these up and attempts to parse them, throwing an unhandled rejection that crashes the dev server:

ERROR [unhandledRejection] .1775487281985 files are not supported.

Reproduction

  1. Start dev server: npm run dev
  2. Create a temporary file inside a content directory: touch content/example.md.tmp.153372
  3. Dev server crashes

Root Cause

The onChange handler in the dev watcher passes all files that match the collection's glob pattern through to the parser. Since the glob matches broadly (e.g. all files under content/), temp files with compound extensions pass through micromatch but fail at the parser which doesn't support the extension.

Fix

Add an early return in onChange for files matching common temporary file patterns before any parsing is attempted:

  • *.tmp, *.tmp.* (most editors/tools)
  • Files ending with ~ (Vim swap)
  • .#* and ~* (Emacs lock files)

Changes

  • src/utils/dev.ts: Skip temp files at the start of onChange

Fixes #3759

Editors and AI tools that use non-atomic writes (write to temp file,
then rename) create intermediate files like `example.md.tmp.153372`.
The content watcher picks these up and attempts to parse them, which
throws an unhandled rejection because the extension is unsupported,
crashing the dev server.

Skip files matching common temporary patterns before attempting to
parse: *.tmp, *.tmp.*, files ending with ~, and Emacs lock files (.#*).

Fixes nuxt#3759
@vercel
Copy link
Copy Markdown

vercel Bot commented May 6, 2026

Someone is attempting to deploy a commit to the Nuxt Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

📝 Walkthrough

Walkthrough

A guard clause was added to the Nuxt Content dev watcher's onChange handler to detect and skip temporary and editor backup files before processing. The implementation extracts the file basename and returns early if it matches common temporary file patterns including .tmp, files ending with , files starting with .#, or files beginning with a tilde (). This prevents the watcher from attempting to parse unsupported file formats that trigger unhandled rejections during non-atomic write operations.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding logic to skip temporary files in the content watcher to prevent crashes.
Description check ✅ Passed The description is well-detailed and directly related to the changeset, explaining the problem, reproduction steps, root cause, and the fix applied.
Linked Issues check ✅ Passed The PR directly addresses issue #3759 by implementing the suggested fix to skip common temporary file patterns in the onChange handler.
Out of Scope Changes check ✅ Passed The changes are limited to src/utils/dev.ts and only add a guard for temporary files, which is entirely within the scope of the linked issue.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/dev.ts`:
- Line 121: The regex in the if condition that inspects basename uses a
capturing group and only allows numeric .tmp suffixes; replace
/\.tmp(\.\d+)*$|~$|^\.#|^\~/ with a non-capturing, broader pattern like
/\.tmp(?:\..+)*$|~$|^\.#|^~/ so it no longer uses a capturing group and matches
any suffix after .tmp (e.g., .tmp.swp); update the if (/.../.test(basename))
expression in src/utils/dev.ts accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1dd1e1f0-5471-4e33-a17c-52589c574ab1

📥 Commits

Reviewing files that changed from the base of the PR and between 55b8793 and 713b2c9.

📒 Files selected for processing (1)
  • src/utils/dev.ts

Comment thread src/utils/dev.ts

// Skip temporary files created by editors and tools during non-atomic writes
const basename = path.split('/').pop() || ''
if (/\.tmp(\.\d+)*$|~$|^\.#|^\~/.test(basename)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix temp-file regex to pass CI and match *.tmp.* broadly.

On Line 121, the regex has an unused capturing group (failing ESLint) and currently narrows .tmp.* to numeric suffixes only. That can still let temp files like foo.tmp.swp reach parsing.

Proposed fix
-    if (/\.tmp(\.\d+)*$|~$|^\.#|^\~/.test(basename)) {
+    if (/\.tmp(?:\..+)?$|~$|^\.#|^~/.test(basename)) {
       return
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (/\.tmp(\.\d+)*$|~$|^\.#|^\~/.test(basename)) {
if (/\.tmp(?:\..+)?$|~$|^\.#|^~/.test(basename)) {
return
}
🧰 Tools
🪛 GitHub Actions: ci / 0_ubuntu.txt

[error] 121-121: ESLint: Capturing group number 1 is defined but never used. (regexp/no-unused-capturing-group)

🪛 GitHub Actions: ci / ubuntu

[error] 121-121: ESLint: Capturing group number 1 is defined but never used. (regexp/no-unused-capturing-group)

🪛 GitHub Check: ubuntu

[failure] 121-121:
Useless identity escapes with non-syntax characters are forbidden


[failure] 121-121:
Unnecessary escape character: ~


[failure] 121-121:
Unnecessary escape character: ~


[failure] 121-121:
Capturing group number 1 is defined but never used

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/dev.ts` at line 121, The regex in the if condition that inspects
basename uses a capturing group and only allows numeric .tmp suffixes; replace
/\.tmp(\.\d+)*$|~$|^\.#|^\~/ with a non-capturing, broader pattern like
/\.tmp(?:\..+)*$|~$|^\.#|^~/ so it no longer uses a capturing group and matches
any suffix after .tmp (e.g., .tmp.swp); update the if (/.../.test(basename))
expression in src/utils/dev.ts accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@nuxt/content crashes on temporary files created during non-atomic writes

1 participant