Skip to content

Block sync for incompatible vault paths - #45

Open
algiadev8 wants to merge 3 commits into
hjinco:mainfrom
algiadev8:feat/block-incompatible-path
Open

algiadev8 wants to merge 3 commits into
hjinco:mainfrom
algiadev8:feat/block-incompatible-path

Conversation

@algiadev8

@algiadev8 algiadev8 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Problem

macOS allows users to create file and folder paths that cannot be applied on Windows.

Previously, these paths could be added to sync, causing errors when a Windows client attempted to apply them.

Summary

  • Prevented paths incompatible with supported platforms from being synced
  • Blocked incompatible local paths before upload
  • Prevented incompatible remote paths from being applied to the local vault
  • Made blocked files visible in the File Explorer and sync settings
  • Updated the existing File Explorer and sync setting tooltip to show guidance specific to incompatible paths

Details

  • Added portable path validation for Windows-incompatible characters, reserved device names, trailing spaces and dots, and other invalid path components
  • Added incompatible_path as a blocked reason
  • Renamed the blocked-file API to listBlockedSyncFiles()
  • Retained the previous listFileSizeBlockedFiles() API and related types as deprecated aliases for backward compatibility
  • Updated File Explorer warning tooltips to explain incompatible paths
  • Updated sync settings to report file-size and incompatible-path blocks separately
  • Added the new UI messages to all supported locales
  • Preserved path whitespace in encrypted metadata so trailing spaces can be detected instead of silently changing the path

Validation

  • Verified with a real vault that paths containing characters such as || are blocked and not synced

@hhhjin

hhhjin commented Sep 15, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 00d3965266

ℹ️ 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".

Comment on lines +51 to +52
if (!isPortableVaultPath(path)) {
return false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Apply tombstones for legacy incompatible paths

When an incompatible path was synced before this upgrade, deletes remain publishable because PushMutationPreparer.prepareMutationForCommit returns for delete operations before validating portability. This unconditional predicate then rejects that tombstone during pull; PullEntryStateApplier merely records its remote state and never removes the existing local file. Consequently, upgraded macOS/Linux clients retain a file that another client deleted while advancing past the deletion, so tombstones for already-tracked incompatible paths need distinct handling from live writes.

AGENTS.md reference: AGENTS.md:L10-L10

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in d4d8887. Remote tombstones now bypass portability filtering, while live remote writes remain blocked, so upgraded clients can remove legacy incompatible paths correctly.

Comment on lines +356 to 358
// TODO: Refresh decorations when an existing blocked file becomes syncable.
if (blockedSyncFiles > 0) {
this.deps.onFileSizeBlockedFilesChange?.();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refresh warnings when an incompatible-path block is cleared

After an incompatible file has been blocked, renaming it to a portable path replaces the blocked mutation with a pending one and the subsequent successful push leaves blockedSyncFiles at zero. Because this callback fires only when the current drain creates a block, neither the settings warning nor the decorator is notified that the old blocked row disappeared; the settings count can remain stale until the pane is reopened, and deleting an unsynced blocked file has the same problem. Emit a blocked-files change when a blocked mutation is replaced or removed as well as when one is created.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for pointing this out. As I understand it, refreshing the UI when a blocked mutation is replaced or removed was not implemented for the existing file-size-blocked flow either, so this appears to be a pre-existing lifecycle-notification gap rather than a regression introduced by incompatible-path blocking. I would prefer to address that broader behavior separately and keep this PR focused on preventing incompatible paths from syncing. Do you think there is a reason this needs to be included in this PR?

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.

2 participants