quartz icon indicating copy to clipboard operation
quartz copied to clipboard

`npx quartz serve` crashes when renaming files

Open husjon opened this issue 1 month ago • 1 comments

Describe the bug When a markdown file is renamed in the content/ folder while npx quartz serve --build is running, it crashes with the error message:

Failed to process markdown `content/Untitled.md`: ENOENT: no such file or directory, open '/tmp/quartz/content/Untitled.md'

To Reproduce Steps to reproduce the behavior:

  1. git clone https://github.com/jackyzha0/quartz.git
  2. cd quartz
  3. npm i
  4. npx quartz build --serve
  5. Create index file touch index.md
  6. Create a second file (e.g. Untitled.md), for example using touch Untitled.md
  7. Rename the file to something else (e.g. test.md) On Linux/Mac this would be using mv Untitled.md test.md
  8. Observe the server failing to process the markdown file.

Expected behavior The file existence should be checked prior to processing and the server should continue running.

Screenshots and Source Here's a quick video showing the steps to reproduce this. This is using the latest commit on main (https://github.com/jackyzha0/quartz/commit/13ff64db97065b5dedbe5164684a0f30e066d967)

https://www.youtube.com/watch?v=j2QhrmlGOv8

Desktop (please complete the following information):

  • Quartz Version: v4.5.2 (also tested using latest main)
  • node Version: v22.21.1
  • npm version: 10.9.4
  • OS: NixOS 26.05 (Yarara)
  • Browser: Vivaldi

Additional context None

husjon avatar Dec 01 '25 21:12 husjon

After some more testing, it seem to be related to chokidar. chokidar emits 2 signals on rename (first an add for the new filename, then delete for the previous filename) It seem that the parsing of markdown files happens before the delete event is triggered and since the file is already removed, the parsing fails. I've annotated the output below to show what happens.

 Quartz v4.5.2

Cleaned output directory `public` in 6ms
Found 0 input files from `content` in 8ms
Parsed 0 Markdown files in 722μs
Filtered out 0 files in 3μs

Warning: you seem to be missing an `index.md` home page file at the root of your `content` folder (`content/index.md does not exist`). This may cause errors when deploying.
Emitted 13 files to `public` in 62ms
Done processing 0 files in 79ms
Started a Quartz server listening at http://localhost:8080
hint: exit with ctrl+c
Detected change, rebuilding...
index.md -> add                                 # <- `add` event due to me creating `index.md`
[ 'content/index.md' ]                          # <- `index.md` added to `pathsToParse`
Parsed 1 Markdown files in 76ms
Filtered out 0 files in 27μs
Emitted 6 files to `public` in 155ms
Done rebuilding in 155ms
Detected change, rebuilding...
Untitled.md -> add                              # <- `add` event due to me creating `Untitled.md`
[ 'content/index.md', 'content/Untitled.md' ]   # <- `Untitled.md` added to `pathsToParse`
â ‹ Parsing input files using 1 threads
Warning: content/Untitled.md isn't yet tracked by git, dates will be inaccurate
Parsed 2 Markdown files in 67ms
Filtered out 0 files in 9μs
Emitted 8 files to `public` in 186ms
Done rebuilding in 187ms
Detected change, rebuilding...
Untitled2.md -> add                             # <- `add` event due to me renaming `Untitled.md` to `Untitled2.md`
[ 'content/index.md', 'content/Untitled.md', 'content/Untitled2.md' ] # <- `Untitled2.md` added to `pathsToParse`
                                                                           Since parsing happens before the `delete` event for `Untitled.md` is triggered, the parsing fails.

 ERROR


Failed to process markdown `content/Untitled.md`: ENOENT: no such file or directory, open '/tmp/quartz/content/Untitled.md'

Here's also an output where the content folder already have the files (in this case index.md and Untitled.md) in the content folder. Untitled.md is then renamed to Untitled2.md and back again to Untitled.md

 Quartz v4.5.2

Cleaned output directory `public` in 4ms
Found 2 input files from `content` in 11ms
â ‹ Parsing input files using 1 threads
Warning: content/Untitled.md isn't yet tracked by git, dates will be inaccurate
Parsed 2 Markdown files in 105ms
Filtered out 0 files in 28μs
Emitted 17 files to `public` in 172ms
Done processing 2 files in 294ms
Started a Quartz server listening at http://localhost:8080
hint: exit with ctrl+c
Detected change, rebuilding...
Untitled2.md -> add                             # <- `add` event due to me renaming `Untitled.md` to `Untitled2.md`
[ 'content/Untitled2.md' ]                      # <- `Untitled2.md` added to `pathsToParse`

Warning: content/Untitled2.md isn't yet tracked by git, dates will be inaccurate
Parsed 1 Markdown files in 44ms
Filtered out 0 files in 7μs
Emitted 6 files to `public` in 105ms
Done rebuilding in 105ms
Detected change, rebuilding...
Untitled.md -> delete                           # <- `delete` event due to me renaming `Untitled.md` to `Untitled2.md` (follow-up from previous event)
[ 'content/Untitled2.md' ]                      # <- `Untitled.md` doesn't exist in the `pathsToParse` array so no difference

Warning: content/Untitled2.md isn't yet tracked by git, dates will be inaccurate
Parsed 1 Markdown files in 44ms
Filtered out 0 files in 4μs
Emitted 6 files to `public` in 96ms
Done rebuilding in 96ms
Detected change, rebuilding...
Untitled.md -> add                              # <- `add` event due to me renaming `Untitled2.md` back to `Untitled.md`
[ 'content/Untitled2.md', 'content/Untitled.md' ] # <- `Untitled.md` added to `pathsToParse`


 ERROR


Failed to process markdown `content/Untitled2.md`: ENOENT: no such file or directory, open '/tmp/quartz/content/Untitled2.md'

husjon avatar Dec 02 '25 14:12 husjon