unslothai/unsloth · error · RuntimeError
Linked folder root identity changed during scan
Error message
Linked folder root identity changed during scan
What it means
After the directory walk completes, _scan re-runs _root_identity(root) and compares to the identity captured before the walk. If the root directory was replaced/remounted while the scan was running, results would describe a mix of two trees, so the scan result is discarded and the error raised.
Source
Thrown at studio/backend/core/rag/folder_sync.py:1011
# rather than abort the scan, which is never authoritative for deletion.
pass
rel = os.path.relpath(full, root).replace(os.sep, "/")
found[rel] = {
"path": full,
"size_bytes": st.st_size,
"mtime_ns": st.st_mtime_ns,
"device": st.st_dev,
"inode": st.st_ino,
# A recovered identity is comparable to the next scan's, but not to os.fstat's:
# shared-folder and WebDAV drivers report different ids for the two call paths.
"identity_from_path": from_path,
}
if config.FOLDER_MAX_FILES and len(found) > config.FOLDER_MAX_FILES:
raise RuntimeError(
f"Folder contains more than the {config.FOLDER_MAX_FILES} supported files limit"
)
if _root_identity(root) != identity:
raise RuntimeError("Linked folder root identity changed during scan")
return found, identity
def _snapshot(root: str, metadata: dict) -> str:
source = metadata["path"]
resolved = os.path.realpath(source)
if not _is_within(root, resolved):
raise RuntimeError("File escaped the linked folder")
# os.fdopen already forces this descriptor binary on Windows; O_BINARY only guards a raw os.read.
flags = os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0) | getattr(os, "O_BINARY", 0)
fd = os.open(source, flags)
target = None
try:
ext = os.path.splitext(source)[1].lower()
target = ensure_dir(rag_uploads_root()) / f"linked-{uuid.uuid4().hex}{ext}"
before = os.fstat(fd)
if not stat.S_ISREG(before.st_mode):
raise RuntimeError("Linked source is not a regular file")View on GitHub (pinned to 203007d190)
Solutions
- Re-run the sync once the folder is stable; the job will re-scan with the new identity if the row was updated, or fail with the identity-changed error if not.
- If the swap was intentional, re-register (or re-authorize) the folder so its stored identity matches the new root.
- Schedule folder replacement outside sync windows to avoid racing the worker.
Defensive patterns
Strategy: retry
Try / catch
try:
result = run_scan(folder_id)
except RuntimeError as e:
if "changed during scan" in str(e):
if folder_row_is_unchanged(folder_id):
result = run_scan(folder_id) # transient swap during walk; retry once
else:
mark_folder_needs_relink(folder_id)
else:
raise Prevention
- Keep the linked root stable while syncs run; do atomic swaps between jobs.
- Re-register the folder after intentional replacements so stored identity matches.
- Schedule syncs when deployment activity is quiet.
When it happens
Trigger: Long scans of big folders where, mid-walk, the root is deleted and recreated, renamed-and-replaced, or its mount is swapped (device id change); deployment scripts doing atomic directory swaps during sync.
Common situations: Atomic deploy replacing the linked folder; container storage re-mounted during a job; the same race as error 570 but caught after the walk instead of before it.
Related errors
- Linked folder changed after it was selected
- Linked source changed during reconciliation
- The linked-folder scope no longer exists
- Linked folder is still being removed
- Linked folder changed while it was reauthorized
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/544b15ab4d8c9547.
Report an issue: GitHub.