Skip to content

fix(notes): rebase sidebar folder paths onto the configured notes root - #1225

Draft
h4yfans wants to merge 1 commit into
mainfrom
folder-paths-notes-root-rebase
Draft

fix(notes): rebase sidebar folder paths onto the configured notes root#1225
h4yfans wants to merge 1 commit into
mainfrom
folder-paths-notes-root-rebase

Conversation

@h4yfans

@h4yfans h4yfans commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Closes #1204

What was wrong

Two producers feed the sidebar tree, and they used different bases:

source base
notes:get-folders (notes-crud.ts getFolders()) notes root (<vault>/<defaultNoteFolder>)
folder nodes synthesised from note.path (buildTreeFromNotes) vault root, minus a hardcoded 'notes' literal

Every consumer is notes-root-relative — folderExists, the folder view's LIKE query, .folder.md
config, createNote({folder}), moveNote. So any node the renderer synthesised was in the wrong
base unless defaultNoteFolder happened to be exactly the string notes.

With defaultNoteFolder = "Notes", notes at Notes/x.md produced a phantom Notes tree node whose
path resolved to <vault>/Notes/Notes. folderExists returned false → folderNotFound
"Folder not found" on the grid button. Same literal appeared in the note breadcrumb, so crumbs opened
the same broken view.

The fix

Rebase note paths onto the configured notes root instead of a hardcoded literal, so the producer
and the consumer agree.

  • stripNotesRoot(notePath, notesRoot) in notes-tree-utils.tsx — tolerant, mirroring
    noteFolderFromPath in @memry/app-core
  • extractFolderFromPath and buildTreeFromNotes take the notes root
  • useNotesRoot() in use-vault.ts — a single string, refreshed on vault status change (changing
    defaultNoteFolder triggers a reindex, which emits one). Deliberately lighter than useVault() so
    the tree does not re-render on index-progress ticks.
  • Threaded through use-note-tree-data (tree build + computeTargetFolder, which feeds
    createNote), use-note-tree-actions (move/drag targets), and note-breadcrumb

The setting is not redefined — defaultNoteFolder stays the notes root, which is what every main
process consumer already implements. No validation-on-write was added: with the producer fixed,
pointing the setting at an existing top-level folder is now a working configuration, so rejecting it
would be wrong.

Backward compatibility

Vault config shape, IPC contracts and on-disk layout are untouched; nothing is moved or migrated.

  • defaultNoteFolder = '' (today's default, no top-level notes/ folder) — no behaviour change.
  • defaultNoteFolder = 'notes' (legacy vaults, and the field's placeholder) — the old hardcoded strip
    and the new configured strip produce identical paths. No change.
  • defaultNoteFolder = '' and a real top-level folder named notes/ — behaviour changes, as a
    fix: those notes used to be hoisted to the tree root while the notes node rendered empty. They now
    nest correctly, matching what getFolders() already reported for that vault.
  • Any other value (the reported case) — the phantom root node disappears and folder paths resolve.
    Reverting the setting to empty still restores the previous view, as before.

Verification

  • pnpm exec vitest run --config config/vitest.config.ts --project renderer over
    notes-tree-utils, use-note-tree-actions, note-sidebar-surfaces, notes-tree,
    virtualized-notes-tree, note, cold-zero-components, cold-major-components, app-sidebar
    → 145 passed
  • pnpm lint → 0 errors · pnpm typecheck → clean · pnpm docs:build → clean
  • pnpm docs:impact --base origin/main --strict → docs changed on this branch

Regression test — notes-tree-utils.test.tsx, "does not emit a folder node for the notes root
itself": defaultNoteFolder = 'Notes', notes at Notes/hello.md and Notes/Work/alpha.md, folders
as getFolders() reports them (['Work']). It asserts the tree's folder paths are exactly ['Work']
— no Notes node for folderExists to reject. Pre-fix, the tree also contained Notes and
rootNotes was empty, so the test fails on main. Existing tests that encoded the hardcoded literal
now pass 'notes' explicitly, preserving their intent.

Known gap (not fixed here)

Notes stored outside the notes root (e.g. Archive/x.md when defaultNoteFolder = 'Notes') are
still indexed and still shown, but their folder node cannot resolve under the notes root, so its grid
button reports "Folder not found". Handling those is a product call — hide them, hoist them to the
tree root, or widen the folder scope to the vault root — and is independent of this fix. Two more
copies of the same hardcoded 'notes' literal remain in
lib/virtualized-tree-utils.ts (getParentFolderId, keyboard nav only) and pages/note.tsx
(backlink folder label, display only); neither produces a folder-view scope.

@github-actions github-actions Bot added bug Something isn't working documentation Improvements or additions to documentation test labels Aug 11, 2026
@github-actions

Copy link
Copy Markdown

React Doctor found no new issues. 🎉

Reviewed by React Doctor for commit e9d6b22.

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

Labels

bug Something isn't working documentation Improvements or additions to documentation test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[MEDIUM][vault] Setting "Default Location for New Notes" to an existing folder makes that folder unbrowsable — "Folder not found"

1 participant