macOS VFS: FileProviderExt crash loop (__FILEPROVIDER_BAD_ITEM_MISSING_IDENTIFIER__) — 405 on folder create embeds DB-derived collision item without identifier; corrupt records then crash change enumeration
- Dominant language
- C++
- Stars
- 3.9k
- Forks
- 1k
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 123
Description
### Bug description
On macOS with virtual files (File Provider), `FileProviderExt` enters a **crash loop**: the FileProvider framework aborts the extension with `__FILEPROVIDER_BAD_ITEM_MISSING_IDENTIFIER__` (SIGABRT). Once triggered, the loop is self-sustaining and the domain silently stops syncing.
The trigger chain, reconstructed from crash reports, the extension's JSONL logs and the `NextcloudFileProviderKit` sources (also vendored in this repo):
1. Bulk-adding a folder tree into the CloudStorage domain leads to a first extension crash mid-`createItem`. The MKCOL had already succeeded server-side, but the extension died before recording the new folder in its local (Realm) database.
2. On retry, MKCOL returns **`405 — The resource you tried to create already exists`**.
3. `NKError.fileProviderError(handlingCollisionAgainstItemInRemotePath:dbManager:remoteInterface:log:)` maps this to `NSFileProviderError(.filenameCollision)` and builds the **embedded "existing item" from the local database** (`itemMetadata(account:locatedAtRemoteUrl:)` → `Item.storedItem(...)`) — **not** from a fresh server PROPFIND. Since the DB has no (or an incomplete) record for that path — precisely what step 1 left behind — the embedded item ends up **without an itemIdentifier**.
4. macOS unwraps the embedded item (`itemFromVendorItem:`) and aborts the extension.
5. The same crash windows leave records with an empty `ocId` in the Realm DB; afterwards **every change-enumeration batch containing such a record crashes the extension too** (`FPXChangesObserver didUpdateItems:` path), so the loop persists even with no pending user operations, across reboots/days.
Two aggravating client bugs make recovery impossible without manual intervention:
- **Credentials are not re-pushed after an extension crash.** The relaunched `FileProviderExt` stays unauthenticated (all ops fail with `NSFileProviderErrorDomain -1000`, backed off by `fileproviderd`) until the desktop client app is fully restarted. Additionally, on client startup the *first* credential push contains an empty password (extension log: `Cancelling domain account setup because "password" is an empty string.`) and only a subsequent push succeeds.
- Items whose `createItem` was in flight during a crash are parked permanently by `fileproviderd` (`next:'never'`, error FP -2005), and their retries can then fail with `400 — Expected filesize of N bytes but read ... 0 bytes` (stale captured content), requiring the files to be deleted and re-created.
### Crash stacks
`createItem` error path (3 of 6 crashes):
```
FileProvider __FILEPROVIDER_BAD_ITEM_MISSING_IDENTIFIER__
FileProvider __FILEPROVIDER_BAD_ITEM__
FileProvider -[FPItem initWithVendorItem:provider:domain:spotlightDomainIdentifier:extensionCapabilities:useFPFS:]
FileProvider -[FPXDomainContext itemFromVendorItem:]
FileProvider -[NSError(FPAdditions) fp_internalErrorForVendorErrorWithCallerDescription:itemCreationBlock:]
FileProvider -[FPXDomainContext internalErrorFromVendorError:callerDescription:]
FileProvider __120-[FPXExtensionContext _createItemBasedOnTemplate:fields:contents:options:request:bounce:bounceNumber:completionHandler:]_block_invoke.641
```
Change-enumeration path (subsequent crashes, fires on every working-set signal):
```
FileProvider __FILEPROVIDER_BAD_ITEM_MISSING_IDENTIFIER__
FileProvider __FILEPROVIDER_BAD_ITEM__
FileProvider -[FPItem initWithVendorItem:provider:domain:spotlightDomainIdentifier:extensionCapabilities:useFPFS:]
FileProvider -[FPXDomainContext itemFromVendorItem:]
FileProvider -[FPXObserver updateForProviderItem:]
FileProvider -[FPXChangesObserver didUpdateItems:]
```
### Extension log excerpts (paths/hostnames redacted)
```
[error] Item: Could not create new folder at: https://cloud.example.com/remote.php/dav/files/user/ParentFolder/NewFolder,
received error: 405
The resource you tried to create already exists
```
```
[info] FileProviderExtension: Received account to configure.
[info] FileProviderExtension: Setting up domain account for user: user, userId: user, serverUrl: https://cloud.example.com, password: , ...
[info] FileProviderExtension: Cancelling domain account setup because "password" is an empty string.
```
After a database reset (attempted recovery), the split-brain state:
```
[error] Not creating item: 00024629xxxxxxxxxxxx, could not find metadata for parentItemIdentifier: 00020474xxxxxxxxxxxx
[error] Could not upload item with filename: document.pdf, received error: 400
Expected filesize of 5668673 bytes but read (from Nextcloud client) and wrote (to Nextcloud storage) 0 bytes.
```
### Steps to reproduce
Not deterministic, but reliably reproduced here twice in one day:
1. macOS client with virtual files / File Provider domain, fully synced.
2. Copy a folder tree (a few new subfolders, ~100 files) into the CloudStorage folder.
3. If the extension crashes once mid-create (for any reason), every subsequent wake crashes: retried folder creates hit 405 → collision item without identifier → abort; later, corrupted DB records crash change enumeration → abort.
### Expected behaviour
- A 405 on MKCOL should never crash the extension: fetch the colliding item's metadata from the server (PROPFIND) when it is not in the local DB, or return a plain `.filenameCollision` error without an embedded item; never hand the framework an item with an empty `itemIdentifier`.
- Enumeration observers should never be given items with empty identifiers (validate/skip corrupt DB records).
- The client should re-authenticate the extension whenever it reconnects (post-crash), not only at app start; the first credential push should not be sent with an empty password.
### Workaround that recovered the installation
Deleting only the domain's Realm DB stops the crashes but leaves the daemon/extension state inconsistent ("could not find metadata for parentItemIdentifier" on every create). Full recovery required **removing and re-creating the File Provider domain** (remove account → re-add), followed by a complete re-enumeration.
### Environment
- Desktop client: 34.0.2, auto-updated to 34.0.3 during the incident (both affected); official builds
- macOS: build 25G83, FileProvider framework 4018.160.6, Apple Silicon
- Server: Nextcloud 34.0.2.1
- Virtual files (File Provider) mode; chunked upload enabled (100 MB)
Full crash reports (`.ips`) and extension JSONL logs are available on request (they need redaction before sharing).
Contributor guide
Assessment
This issue has not been assessed yet.