Skip to content

Bug: verify() lock fails on exFAT filesystems due to 10ms timestamp resolution #16

@tristansokol

Description

@tristansokol

Hi!

I have my vault on an external drive (exFAT) and ob sync fails with "Another sync instance is already running for this vault" evenwhen no other instance is running. The lock can never be acquired and I've tried manually deleting it even without success.

Root cause

The verify() method in the DirLock class uses strict equality to compare the timestamp it wrote via utimesSync against what statSync reads back:

  verify(){return this.lockTime===this.get()}

exFAT has a 10ms timestamp resolution (https://learn.microsoft.com/en-us/windows/win32/fileio/exfat-specification#749-timestamp-fields). utimesSync rounds to the nearest 10ms boundary, producing drifts of up to ~10ms:

This is related to #9 (floating-point mtime precision on ext4), but a different root cause — exFAT's coarse resolution vs float rounding.

Environment

  • obsidian-headless v0.0.8
  • Node.js v25.2.0
  • Ubuntu 24.04, Linux 6.x

Reproduction

  1. Place a vault on an exFAT-formatted drive
  2. ob sync-setup --vault "Name"
  3. ob sync → always fails with "Another sync instance is already running"

Workaround

Patching verify() in cli.js:

  verify(){return Math.abs(this.lockTime-this.get())<20}

Suggested fix

Increase the tolerance to ~20ms. This covers exFAT (10ms) with margin, while still being tight enough to detect genuinely stale locks (which are checked against a 5-second window in acquire()). This would also subsume the #9 fix for float precision.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions