[Android] A single uncreatable file (filename > 255 bytes) fails the startup scan, which silently gates all replication behind "Not ready"
Summary
On Android, one document whose filename exceeds the filesystem's 255-byte limit causes the startup full scan to report 1 failed. Because prepareDatabaseForUse only calls appLifecycle.markIsReady() when vault.scanVault() returns true, and the scanner returns failedCount === 0, the plug-in never reaches the ready state. Every replication path (Sync now, Sync with a saved connection, LiveSync mode) is then refused with only the two-word log line [ReplicationService] Not ready, and no notice is shown. The device stops syncing in both directions.
The same vault syncs correctly on Windows, where the 255 limit is counted in characters rather than bytes, so the file is created without error and the scan passes.
A second, smaller issue surfaced while working around the first: the "Non-Synchronising files" regex list strips all spaces before compiling, so a pattern containing spaces can never match.
Environment
- Self-hosted LiveSync 1.0.24 (
@vrtmrz/livesync-commonlib0.1.21) - Android 17, Pixel 11 Pro XL, WebView Chrome/152
- Obsidian mobile (current)
- Remote: self-hosted CouchDB,
remoteConfigurations.legacy-couchdbactive, E2EE off - Desktop: Windows 11, same plug-in version — syncs normally
Steps to reproduce
- On a desktop client, create a note whose filename is ≤ 255 characters but > 255 bytes in UTF-8 (e.g. ~250 characters including a few curly quotes
“ ”, which are 3 bytes each). Windows/NTFS accepts it. - Let it replicate to CouchDB and then to an Android client.
- Restart Obsidian on Android and open the LiveSync log.
Actual behaviour
Log on Android (verbose):
[ServiceFileHandler] File Work/<folder>/<261-byte name>.md (forced)
Error processing Work/<folder>/<261-byte name>.md with action update-storage
Error:FILE_NOTCREATED
[StackTrace]: _LiveSyncError: [Error Logged]: FILE_NOTCREATED
at processFilePair (plugin:obsidian-livesync:6:386401)
[CausedBy]: Error
at win.androidBridge.onmessage (http://localhost/:890:21)
[SF:OfflineScanner] Synchronisation completed: 8401 files processed (4183 completed, 4217 skipped, 1 failed)
[SF:OfflineScanner] Initialized, NOW TRACKING!Then, on Sync now, Switch active connection, or Sync with a saved connection:
Switched to remote: CouchDB Remote (Active)
[ReplicatorService] Active replicator has been kept
[ReplicationService] Not readyStatus bar shows Sync: ■ ↑0 ↓0. No notice or dialogue is shown. The compatibility review had already been completed (the Review why synchronisation is paused command is not offered). Nothing replicates in either direction until the failing document is excluded.
Expected behaviour
One file that cannot be materialised on this platform should be reported (ideally with a persistent notice naming the file) and skipped, and replication should continue for the other 8,400 files. At minimum, the readiness gate should say why it is not ready rather than the bare Not ready.
Root cause (from reading 0.1.21 dist)
services/base/ReplicationService.readiness.ts— theapplication-readycondition logs"Not ready"and returnsfalsewhenappLifecycleService.isReady()is false. This is the only diagnostic emitted.serviceFeatures/prepareDatabaseForUse.ts— callsappLifecycle.resetIsReady()first, then returnsfalse(without logging) ifvault.scanVault()returnsfalse, somarkIsReady()is never reached.serviceFeatures/offlineScanner.ts—synchroniseAllFilesBetweenDBandStoragereturnsfailedCount === 0;performFullScanreturns that result unchanged as thescanVaulthandler's result.
So one FAILED pair from processFilePair → scan returns false → app never marked ready → all replication gated, silently.
There is also a chicken-and-egg consequence: the failing document lives in the local database, so renaming it on another device cannot help — the Android client cannot receive the rename until it replicates, and it cannot replicate until the scan passes.
Suggested fixes
- Treat per-file
FILE_NOTCREATED(and similar platform-storage failures) as non-fatal for readiness: report and skip the pair, or raise an unresolved-error notice naming the path, but still mark the app ready so replication proceeds. - Have
prepareDatabaseForUselog which step failed (openDatabase,isDatabaseReady,scanVault,onDatabaseInitialised,commitPendingFileEvents) when it returnsfalse, and have the readiness evaluator surface that reason instead ofNot ready. - Optionally, warn when a document's path exceeds 255 bytes in UTF-8, since that is the effective limit on Android/Linux and iOS, while Windows counts UTF-16 characters.
Second issue: "Non-Synchronising files" regex list strips spaces
common/utils.ts → parseCustomRegExpList:
const items = source.replace(/\n| /g, "").split(d).filter((e) => e);Every space in the stored pattern list is removed before new RegExp(...). A pattern such as Brook and the Stauffers is compiled as BrookandtheStauffers and never matches; the UI (PaneSelector.ts → MultipleRegExpControl) accepts it without warning. Brook.and.the.Stauffers works. Suggest either not stripping spaces (splitting only on the |[]| delimiter) or rejecting/escaping spaces in the control with a hint.
Workaround that resolved it
- General Settings → Extra menus → Enable advanced features (the Selector pane is otherwise hidden).
- Selector → Non-Synchronising files → add a space-free pattern matching the offending filename.
- Force-close and reopen Obsidian. Scan completes with
0 failed,markIsReady()is reached, replication starts, and the client pulls the rename made on the desktop. - Remove the pattern afterwards.
Relationship to #1148
The symptom (Not ready on Android, desktop fine) looks like #1148, but that report shows [ReplicatorService] No remote replicator configuration found and InitialiseFatalError at startup. Neither appears here; the active configuration is present and the failure is entirely the scan-result gate. Filing separately, but linking in case the readiness diagnostics fix covers both.
Full debug report available on request (CouchDB URI and credentials redacted).
Source: vrtmrz/obsidian-livesync