unslothai/unsloth · warning · ValueError
Linked folder is still being removed
Error message
Linked folder is still being removed
What it means
Inside create_folder's duplicate-detection loop: when the new path matches an existing linked_folders row (same path key or os.path.samefile) but that row has status='retired' or a pending delete_remove_index, the folder is mid-teardown and cannot be re-authorized, so creation aborts instead of resurrecting a half-deleted row.
Source
Thrown at studio/backend/core/rag/folder_sync.py:256
folder_id = str(uuid.uuid4())
now = _now()
with _scope_lock(scope):
conn = rag_db.get_connection()
try:
conn.execute("BEGIN IMMEDIATE")
if conn.execute(
"SELECT 1 FROM linked_folder_retired_scopes WHERE scope=?", (scope,)
).fetchone():
raise ValueError("The linked-folder scope no longer exists")
normalized_key = _path_key(normalized)
existing = conn.execute(
"SELECT * FROM linked_folders WHERE scope=?", (scope,)
).fetchall()
for row in existing:
existing_key = _path_key(row["path"])
if existing_key == normalized_key or _same_file(row["path"], normalized):
if row["status"] == "retired" or row["delete_remove_index"] is not None:
raise ValueError("Linked folder is still being removed")
conn.rollback()
return _reauthorize_folder(row["id"], normalized, expected_identity)
if _paths_overlap(existing_key, normalized_key):
raise ValueError("Linked folders in the same scope cannot overlap")
try:
current_identity = _root_identity(normalized)
except RuntimeError as exc:
raise ValueError(str(exc)) from exc
if current_identity != (root_device, root_inode) or (
expected_identity is not None and current_identity != expected_identity
):
raise ValueError("Linked folder changed after it was selected")
conn.execute(
"INSERT INTO linked_folders(id, scope_type, scope_id, scope, path, name, "
"root_device, root_inode, auto_sync, status, created_at, updated_at) "
"VALUES(?,?,?,?,?,?,?,?,?,?,?,?)",
(
folder_id,View on GitHub (pinned to 203007d190)
Solutions
- Wait for the removal job to reach terminal state (status in {'completed','failed'}) and the row to disappear, then retry create_folder.
- Poll the folder status/jobs API for the same path before retrying instead of retrying immediately.
- If a row is stuck retired with no running job (e.g. after a crash), run the reconciliation/cleanup path so the retire job completes.
Defensive patterns
Strategy: retry
Validate before calling
# No public helper exists; approximate by checking the row state directly.
import sqlite3
from storage import rag_db
def folder_ready_for_relink(path_key: str, scope: str) -> bool:
with closing(rag_db.get_connection()) as conn:
rows = conn.execute("SELECT status, delete_remove_index FROM linked_folders WHERE scope=?", (scope,)).fetchall()
return not any(r["status"] == "retired" or r["delete_remove_index"] is not None for r in rows) Try / catch
try:
create_folder(...)
except ValueError as e:
if "still being removed" in str(e):
schedule_retry_after_removal_completes(path) # backoff until terminal
else:
raise Prevention
- Wait for remove_folder's job to reach completed/failed before offering re-add in the UI.
- Never fire add and remove for the same path concurrently.
- Monitor retire-job progress and only then re-enable the link button.
When it happens
Trigger: Re-linking the same directory while a previous unlink/delete job (which may still be removing indexed chunks) is in flight; retrying a create immediately after a remove_folder call; crash-recovery reruns where the retire job hasn't reached terminal state yet.
Common situations: User removes a folder and instantly re-adds it; background delete worker is slow because the RAG index is large; the delete job is queued behind another sync for the same folder.
Related errors
- The linked-folder scope no longer exists
- Linked folder changed after it was selected
- Linked folder changed while it was reauthorized
- Linked folder root identity changed during scan
- Linked folder no longer resolves to its registered path
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/71510add388b32c2.
Report an issue: GitHub.