fix(splitOnHeading): await async note creation + include heading in replace search - #139
Open
Milofax wants to merge 2 commits into
Open
fix(splitOnHeading): await async note creation + include heading in replace search#139Milofax wants to merge 2 commits into
Milofax wants to merge 2 commits into
Conversation
splitOnHeading() iterated over heading sections with forEach without awaiting createNoteWithFirstLineAsFileName(). Each invocation performs a read-modify-write on the document via: doc.setValue(doc.getValue().replace(originalContent, contentToInsert)) When all calls fired concurrently, each read the document state at roughly the same time and the writes overwrote each other — only the last write survived. The result: content of all other heading sections remained in the original note, leading to duplication (content present both in the new per-heading notes and in the original). Replacing forEach with a for loop and awaiting each call serialises the read-modify-write cycle, so each replacement sees the document state produced by the previous one. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t wrong-line replacement
When excludeFirstLineInNote is enabled (default in many setups), noteContent()
returns the section body without the heading line. Passing only that body as
the search string to replaceContent (which does
doc.setValue(doc.getValue().replace(originalContent, link))) causes
String.prototype.replace to find the first occurrence of the body text
anywhere in the document — including inside a subsequent heading line.
Concrete failure observed in user vault with a German short-text note:
Source:
## Test1
Test 1
## Test 2
Test 2
After 'Split note by headings - H2', the second iteration searched for
"Test 2" and matched the heading "## Test 2" before the body, producing:
## Test1
[[Test1]]
## [[Test 2]] <-- heading corrupted, body left in place
Test 2
For 'replace-headings' mode, build the search string from the full
selectedContent (heading + body) so the replace anchors on the entire section
block. Other modes are unaffected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Author
|
Added a second commit that fixes a related issue surfaced once the race condition is gone: When The fix: for 🤖 Generated with Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When running
Split note by headings - H{1,2,3}on a note with multiple matching headings, the content of the heading sections remains in the original note while also being copied into the new per-heading notes — i.e. content is duplicated instead of moved.According to the README, the expected behaviour is that the heading sections are moved out of the original (replaced by links to the new notes). The bug surfaces consistently when
Refactored Note Templateis configured (extra async calls widen the race window), but the underlying race exists unconditionally.Root cause
splitOnHeading()iterated over sections withforEach, not awaiting the asynccreateNoteWithFirstLineAsFileName()calls:Each invocation performs a read–modify–write on the document via
doc.setValue(doc.getValue().replace(originalContent, contentToInsert))(src/doc.ts,replaceContent()formode === 'replace-headings'). Running the calls concurrently means each one reads the document at roughly the same time and the writes overwrite each other — only the last write survives, so all other sections' content is left untouched in the original note.Fix
Replace the parallel
forEachwith a sequentialfor+awaitso eachreplaceContentsees the document state produced by the previous one:No API changes, no behaviour change for users beyond the fix.
Test plan
npm run build) and verified the compiledmain.jsnow contains a sequentialyield-based loop instead of a parallelforEach.Refactored Note Template: triggerSplit note by headings - H2→ confirm the original note now contains only the link to each new note (not the original section bodies) and each new note contains exactly its respective section.Refactored Note Template— confirm still works.🤖 Generated with Claude Code