Symlink Operations¶
This page is the canonical reference for how DUMB uses, repairs, migrates, snapshots, and restores symlink libraries.
It covers:
- Path model and service-specific symlink roots
- Repair modes and when to use each one
- Snapshot backup/restore and scheduled backups
- Safe migration playbooks (including Decypharr beta path changes and individual -> combined roots)
- Frontend option behavior and backend API behavior
- Troubleshooting and recovery
Why symlinks matter in DUMB¶
In DUMB workflows, services like Decypharr, NzbDAV, CLI Debrid, and Riven create curated symlink libraries that point to mounted content (for example rclone/DFS paths under /mnt/debrid).
This gives you:
- Clean, curated libraries for media servers
- Separation between raw mount trees and user-facing libraries
- Faster migration paths when providers or mount layouts change
Common failure mode:
- A symlink exists, but its target path no longer exists after mount/path changes.
Path model (high level)¶
Typical roots inside the container:
- Raw/mount content roots:
/mnt/debrid/decypharr/mnt/debrid/clid/mnt/debrid/nzbdav/mnt/debrid/riven
- Curated symlink library roots:
/mnt/debrid/decypharr_symlinks/mnt/debrid/nzbdav-symlinks/mnt/debrid/clid_symlinks/mnt/debrid/combined_symlinks/mnt/debrid/riven_symlinks
Important:
- Symlink targets are path-sensitive. If the target path changes, links may break until repaired/migrated.
Supported service workflows¶
Decypharr¶
- Arr requests route to Decypharr.
- Decypharr resolves content in debrid-backed mount paths.
- Arr rename/import behavior produces curated symlink results for library paths.
- Common migration: provider-layout path rewrite (for example
realdebrid/__all__->__all__).
NzbDAV¶
- Arr workflow uses NzbDAV download-client flow.
- Final libraries are curated symlink paths under NzbDAV roots or combined roots.
CLI Debrid¶
- CLI Debrid can create symlinks from mounted content into
/mnt/debrid/clid_symlinks. - A frequent use case is cloning/migrating these entries into another symlink tree for downstream import workflows.
Riven¶
- Uses configured
symlink_library_path. - Included in backend defaults when configured.
DUMB symlink tools¶
DUMB provides three categories of symlink operations:
- Repair/migration (
POST /api/process/symlink-repair)- Async apply mode:
POST /api/process/symlink-repair-asyncGET /api/process/symlink-job-statusGET /api/process/symlink-job-latest
- Async apply mode:
- Standalone snapshot backup/restore (
POST /api/process/symlink-manifest/backup,POST /api/process/symlink-manifest/restore)- Compare/preview mode:
GET /api/process/symlink-manifest/compare
- Async backup/restore modes:
POST /api/process/symlink-manifest/backup-asyncPOST /api/process/symlink-manifest/restore-asyncGET /api/process/symlink-job-status
- Compare/preview mode:
- Scheduled snapshot backup and restore selection (
/api/process/symlink-backup-*)
See API details: Process Management API.
Repair modes (what each one does)¶
1) Prefix rewrite mode¶
Use when link targets changed path prefix but links should stay in-place.
Example:
- From:
/mnt/debrid/decypharr/realdebrid/__all__/... - To:
/mnt/debrid/decypharr/__all__/...
Behavior:
- Scans symlink entries in selected roots
- Rewrites target strings that match
from_prefix - Leaves symlink file location unchanged
2) Preset rewrite mode¶
Use for known migrations with built-in rules.
Current preset:
decypharr_beta_consolidated
Behavior:
- Same as prefix rewrite, but rule set is predefined.
3) Root migration mode¶
Use when symlink files themselves must move between library trees.
Example:
- From:
/mnt/debrid/decypharr_symlinks/... - To:
/mnt/debrid/combined_symlinks/...
Behavior:
- Preserves relative path under the destination root
- Supports:
- move (default)
- copy (
copy_instead_of_move: true) for staged transition/import
Frontend option behavior (important details)¶
Roots behavior¶
Roots overridereplaces defaults for that run (it does not append).Add root from common pathsis a UI helper that appends selected paths into theRoots overridetextbox.- In current Symlink Repair UI:
- choose a Playbook for common migrations, or custom modes
- root override controls are shown for prefix-rewrite playbooks
- preset rewrite playbook uses service-scoped defaults for the current service page
- root migration playbooks use explicit
from_rootandto_root
Service-scoped defaults (repair UI)¶
On each service page, default repair scope is narrowed to that service root unless overridden:
- Decypharr page ->
/mnt/debrid/decypharr_symlinks - NzbDAV page ->
/mnt/debrid/nzbdav-symlinks - CLI Debrid page ->
/mnt/debrid/clid_symlinks - Riven page ->
symlink_library_path(or/mnt/debrid/riven_symlinksfallback)
Backup manifest on apply¶
Repair UI supports automatic backup manifest creation on apply runs:
- Auto-backup enabled by default
- If no explicit path is provided, a timestamped path is generated
This gives you rollback/audit artifacts without manual setup each run.
Snapshot backup / restore¶
Snapshot tab behavior:
Manifest pathnow includes a dropdown picker of existing snapshot files (same directory scan behavior as scheduled restore), plus aCustom pathoption.Manifest pathremains fully editable whenCustom pathis selected.- Restore flow includes Preview changes to compare the selected manifest against current symlinks using current restore options (
overwrite_existing,restore_broken). - Backup root scope defaults to
Current service rooton the active service page. - Managed default manifest path now follows snapshot root selection:
- current/specific root =>
/config/symlink-repair/snapshots/{service}.json - all default roots =>
/config/symlink-repair/snapshots/latest.json
- current/specific root =>
- Backup root scope supports:
- Current service root
- All default roots
- A specific known root
- Custom roots (textarea)
Standalone backup¶
Create snapshot manifest:
{
"backup_path": "/config/symlink-repair/snapshots/latest.json",
"roots": ["/mnt/debrid/decypharr_symlinks"],
"include_broken": true
}
Restore from snapshot¶
{
"manifest_path": "/config/symlink-repair/snapshots/latest.json",
"dry_run": true,
"overwrite_existing": false,
"restore_broken": true
}
Recommended flow:
- Run restore in dry-run mode
- Review output
- Apply with confirmation when expected
ELI5: which button should I use?¶
Think of symlinks like shortcut files.
- If the shortcut is in the right folder, but points to the wrong place:
- use Repair with prefix rewrite (or preset)
- If you want shortcuts to live in a different folder:
- use Repair with Move symlink entries between roots
- If you want shortcuts copied into a new folder, but keep originals:
- use Move symlink entries between roots with copy mode
- If you are nervous about changes:
- take a Snapshot backup first
- If you want automatic safety backups:
- use Schedule and set interval + retention
Simple examples:
- "My CLI Debrid links should also exist for Decypharr/Arr":
- move/copy from
/mnt/debrid/clid_symlinksto/mnt/debrid/decypharr_symlinks
- move/copy from
- "My CLI links still live in
clid_symlinks, but target path changed":- rewrite target prefix from old mount path to new mount path
- "I just want to test before touching anything":
- click Dry run first
Golden rule:
- Dry run first
- Then apply
- Keep backup manifest enabled
Scheduled backup behavior¶
Enabled with service config keys:
symlink_backup_enabledsymlink_backup_intervalsymlink_backup_start_timesymlink_backup_pathsymlink_backup_include_brokensymlink_backup_roots(optional override)symlink_backup_retention_count
Retention¶
symlink_backup_retention_count = 1is the default when unset0disables pruning (keep all matching manifests)- Values
> 0keep newestN, pruning older files matching the service template
Default cadence¶
- Default
symlink_backup_intervalis168hours (weekly) unless overridden.
Restore from scheduled backups¶
Use the Schedule tab dropdown to pick an available manifest discovered from the configured template.
Migration playbooks¶
Playbook A: Decypharr beta provider path consolidation¶
Use preset rewrite:
{
"dry_run": true,
"presets": ["decypharr_beta_consolidated"]
}
Then apply:
{
"dry_run": false,
"presets": ["decypharr_beta_consolidated"],
"backup_path": "/config/symlink-repair/decypharr-rewrite.json"
}
Playbook B: Individual -> combined symlink roots¶
{
"dry_run": false,
"root_migrations": [
{
"from_root": "/mnt/debrid/decypharr_symlinks",
"to_root": "/mnt/debrid/combined_symlinks"
}
]
}
Playbook C: Clone CLI Debrid symlinks into Decypharr tree¶
{
"dry_run": false,
"root_migrations": [
{
"from_root": "/mnt/debrid/clid_symlinks",
"to_root": "/mnt/debrid/decypharr_symlinks"
}
],
"copy_instead_of_move": true
}
Use this when you want to seed/import existing curated content into another service’s expected symlink root without deleting originals.
Playbook D: Move CLI Debrid symlinks into Decypharr tree (cutover)¶
{
"dry_run": false,
"root_migrations": [
{
"from_root": "/mnt/debrid/clid_symlinks",
"to_root": "/mnt/debrid/decypharr_symlinks"
}
],
"copy_instead_of_move": false
}
Use this when you are done with the old tree and want a true move.
Playbook E: Retarget CLI Debrid symlink targets from clid mount to Decypharr mount¶
Use custom prefix rewrite on CLI Debrid root:
{
"dry_run": false,
"roots": ["/mnt/debrid/clid_symlinks"],
"rewrite_rules": [
{
"from_prefix": "/mnt/debrid/clid/",
"to_prefix": "/mnt/debrid/decypharr/__all__/"
}
]
}
Notes:
- This rewrites existing link targets in-place.
- Exact
to_prefixshould match your active Decypharr mount layout. - Dry-run first to confirm expected match count.
Playbook F: Cross-service import seeding for Arrs¶
Goal: make existing non-Arr symlink libraries importable by Arr workflows.
Suggested sequence:
- Snapshot backup source + destination roots.
- Run root migration in copy mode (
copy_instead_of_move: true) from source root to Arr-consumed root. - Validate imports in Arr.
- Optionally run cleanup move/remove after stable import.
Playbook G: Combined root adoption without losing existing libraries¶
When switching to /mnt/debrid/combined_symlinks:
- Copy individual roots into combined root first.
- Update consumers/importers to combined root.
- Monitor and validate.
- Move or archive old roots after confirmation.
Playbook H: Recovery from bad apply¶
If an apply run produced unwanted results:
- Use the apply-time backup manifest (or latest snapshot manifest).
- Run restore with
dry_run: true. - If output looks correct, run apply restore.
- Re-run targeted repair only if needed.
Safe operating checklist¶
Before apply runs:
- Verify service and root scope (avoid broad accidental rewrites)
- Run dry-run first
- Confirm backup manifest path/auto-backup
- Apply with confirmation
- Validate sampled symlinks + Arr/media-server visibility
For large migrations:
- Snapshot backup first
- Prefer copy mode for staged cutovers
- Validate import behavior
- Switch consumers to new root
- Cleanup old root once stable
Do Arr apps need updates after symlink changes?¶
Short answer: sometimes.
Use this quick map:
-
Prefix rewrite only (targets changed, symlink root stayed the same):
- Arr changes usually: No
- Why: Arr still sees the same symlink path; only the underlying target changed.
-
Root migration/copy to a new symlink tree that Arr will now use:
- Arr changes usually: Yes
- Why: Arr import/root assumptions may still point at old paths.
-
Clone CLI Debrid symlinks into Decypharr tree for import seeding:
- Arr changes usually: Yes (at least one-time import/discovery)
- Why: Arr did not create these symlinks, so they are usually unknown to Arr until Manual Import (or equivalent discovery/import action).
-
Move from individual roots to
combined_symlinksas primary workflow:- Arr changes usually: Yes
- Why: completed import source path and/or related path mappings often need to align with combined layout.
-
Snapshot backup/restore only:
- Arr changes usually: No
- Why: this restores symlink state, not Arr configuration.
What to update in Arr when required¶
When you switch Arr-facing paths, review these in each Arr instance:
-
Download/import source path assumptions
- Ensure the path Arr receives from the download workflow is still valid after migration.
-
Remote Path Mappings (when Arr sees different paths than DUMB)
- If Arr runs in a different container/host namespace, update mappings so Arr can translate source paths.
-
Root folders (managed library destination)
- If your managed destination path changed, update Arr Root Folders for future imports.
-
Manual Import source path (for seeding workflows)
- For one-time seeding, point Manual Import at the copied destination tree (for example
/mnt/debrid/decypharr_symlinks).
- For one-time seeding, point Manual Import at the copied destination tree (for example
-
Validation
- Run one test import after migration.
- Confirm no path mismatch warnings in Arr logs.
- Confirm media server paths still resolve.
Practical examples¶
-
Example A:
retarget_clid_mount_to_decypharr- Arr update: Yes (usually one-time Manual Import/discovery for existing items)
- Reason: even if symlink paths are valid, Arr often has no item records for symlinks it did not create.
-
Example B:
copy_clid_to_decypharr- Arr update: Yes (one-time Manual Import/discovery)
- Arr update: Yes for ongoing workflow switches if path assumptions/mappings also change.
-
Example C:
move_individual_to_combined- Arr update: usually Yes
- Update source-path assumptions and any remote path mappings.
Troubleshooting¶
Symptom: Restore/repair shows no changes¶
Check:
- Selected roots actually contain symlinks
- Prefix/preset matches existing target strings exactly
- You are not accidentally scoped to the wrong service root
Symptom: CLI -> Decypharr migration succeeds but Arr import still misses items¶
Check:
- Arr download/import root actually points at the destination symlink tree.
- Relative directory depth expected by Arr matches copied/moved tree.
- Source links were copied (not moved) if you still depend on CLI tree.
Symptom: Prefix rewrite changed fewer links than expected¶
Check:
from_prefixincludes trailing slash behavior exactly as stored in symlinks.- Some links may point to mixed provider layouts; run additional rewrite passes if needed.
- Include-broken setting may be excluding currently broken links.
Symptom: Media server sees broken links¶
Check:
- Target paths exist in the same namespace the media server uses
- Host/container bind mounts preserve expected absolute paths
- Symlink targets resolve from the media server runtime context
Symptom: Scheduled backups not appearing¶
Check:
symlink_backup_enabledis true- Path template includes writable destination
- Schedule status endpoint reports next/last run
- Manifest list endpoint pattern matches your template
Symptom: Snapshot restore says manifest missing even though file exists¶
Check:
- Snapshot
Manifest pathdropdown currently selected a real file and notCustom pathwith stale text. - Path exists inside the container namespace (not host-only path).
- File permissions allow DUMB process user to read manifest.
API references¶
- Process Management API
/process/symlink-repair/process/symlink-manifest/backup/process/symlink-manifest/backup-async/process/symlink-job-status/process/symlink-job-latest/process/symlink-manifest/restore/process/symlink-manifest/restore-async/process/symlink-manifest-files/process/symlink-backup-status/process/symlink-backup-manifests/process/symlink-backup/reschedule
Related service pages: