fix: prevent Templater double-execution race with Modal Forms#1090
fix: prevent Templater double-execution race with Modal Forms#1090
Conversation
When trigger_on_file_creation is enabled, stop suppressing it and then also calling overwriteTemplaterOnce() - this created a race window where both could fire, causing Modal Forms dialogs to appear twice. Instead, use mutual exclusion: pick exactly ONE runner for new files.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR fixes a race condition causing modal forms to execute twice when using QuickAdd with templates. Changes to Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d789670076
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // If trigger-on-create is enabled, let Templater's auto-trigger handle it. | ||
| // If disabled, suppress auto-trigger and run explicitly via overwriteTemplaterOnce. | ||
| // This mutual exclusion prevents the double-execution race in #1084. | ||
| const triggerOnCreate = isTemplaterTriggerOnCreateEnabled(this.app); | ||
| const suppressTemplaterOnCreate = !triggerOnCreate && filePath.toLowerCase().endsWith(".md"); |
There was a problem hiding this comment.
Preserve post-process-before-Templater ordering
When trigger_on_file_creation is enabled, this path intentionally skips suppression (triggerOnCreate → suppressTemplaterOnCreate = false), but the code still mutates front matter immediately after creation. Because Templater’s auto-trigger can fire before or concurrently with that post-processing, it can read unprocessed front matter (arrays coerced to strings, date tags not converted) or have its own front-matter edits overwritten by the later postProcessFrontMatter call. This breaks the existing assumption/tests that post-processing happens before Templater runs. To avoid this race, you still need a mutual exclusion mechanism (e.g., suppress until post-processing finishes, then allow the auto-trigger or explicitly call Templater once).
Useful? React with 👍 / 👎.
Deploying quickadd with
|
| Latest commit: |
d789670
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://003e6a56.quickadd.pages.dev |
| Branch Preview URL: | https://1084-bug-modal-forms-breakin-ezw9.quickadd.pages.dev |
Summary
Fixes #1084 - Modal Forms dialogs appearing twice when using QuickAdd templates.
Root Cause Analysis
The bug was a race condition between two independent Templater execution paths:
trigger_on_file_creationsetting)overwriteTemplaterOnce())The Problematic Flow (Before)
The core issue: suppression ended before the explicit overwrite call, creating a window where Templater's auto-trigger could sneak through.
Why Timing-Based Fixes Don't Work
The Fix: Mutual Exclusion
Pick ONE runner, not both. For newly created files:
trigger_on_file_creationwaitForTemplaterTriggerOnCreateToComplete()overwriteTemplaterOnce()This eliminates the entire class of "auto-trigger starts late" races by ensuring exactly one of {auto-trigger, explicit overwrite} runs.
The New Flow (After)
When
trigger_on_file_creationis enabled:When
trigger_on_file_creationis disabled:Changes
src/engine/TemplateEngine.tscreateFileWithTemplate(): CheckisTemplaterTriggerOnCreateEnabled()to decide strategyoverwriteTemplaterOnce()src/engine/CaptureChoiceEngine.tsonCreateFileIfItDoesntExist(): Same mutual exclusion logic for capture-with-template flowsTest Plan
trigger_on_file_creationenabled: form should appear exactly oncetrigger_on_file_creationdisabled: form should appear exactly onceoverwriteFileWithTemplatebehavior unchanged (modifies existing files, not affected by trigger-on-create)Compatibility Notes
This changes behavior for users who have
trigger_on_file_creationenabled:This should be transparent to users since the end result is the same (Templater processes the template), but now it happens via the auto-trigger path instead of QuickAdd's explicit call.
Summary by CodeRabbit
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.