fix: abort sync on PermissionError to prevent destructive index reconciliation#1028
fix: abort sync on PermissionError to prevent destructive index reconciliation#1028sanjibani wants to merge 2 commits into
Conversation
The basicmemory.com docs site restructured: /getting-started/note-formatting and /guides/cli-reference both 404, replaced with the canonical /concepts/knowledge-format and /reference/cli-reference paths (the old /guides prefix was renamed to /reference). The basicmemory.com/subscribe landing page was retired and now redirects to /pricing. Verified via curl: GET on the new URLs returns 200. Signed-off-by: sanjibani <18418553+sanjibani@users.noreply.github.com>
…ciliation (GH#1007) scan_directory() was catching PermissionError on the project root, logging a warning, and returning an empty iterator. The calling code then saw file_count=0, selected the full_deletions strategy, and deleted every indexed entity. Changes: - scan_directory(): raise SyncFatalError instead of returning on PermissionError - _quick_count_files(): propagate SyncFatalError from scan_directory() fallback - scan(): catch SyncFatalError from _quick_count_files (select-scan-strategy phase) and from await scan_coro (full-scan phase), returning early without updating watermarks or reconciling deletions - Updated test_scan_directory_handles_permission_error to expect SyncFatalError (subdirectory PermissionError now propagates too) - Added test_sync_aborts_and_preserves_index_when_root_dir_inaccessible
|
|
|
recheck |
|
@sanjibani Thank you for digging into this and for adding a regression test. The underlying safety concern is absolutely valid: an unreadable project root or subtree must never look like an empty successful scan and trigger destructive deletion reconciliation. Since this PR was opened, #1054 merged a replacement for the old I'm closing this as superseded, not rejected—the report and test scenario were useful and align with the safeguards now on |
Summary
scan_directory(): raiseSyncFatalErrorinstead of returning onPermissionError_quick_count_files(): propagateSyncFatalErrorfromscan_directory()fallbackscan(): catchSyncFatalErrorfrom both_quick_count_files(count phase) andawait scan_coro(full-scan phase), returning early without updating watermarks or triggering deletion reconciliationFixes GH#1007
When
aiofiles.os.scandir()raisesPermissionErroron the project root, the sync now aborts immediately instead of representing the inaccessible root as an empty successful scan. This prevents thefull_deletionsstrategy from deleting every indexed entity.Test changes
test_scan_directory_raises_on_permission_errorto expectSyncFatalError(subdirectory permission errors now propagate)test_sync_aborts_and_preserves_index_when_root_dir_inaccessibleregression test