You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On beta, a Premiumize entry that was found by sync is listed as a folder over WebDAV but serves none of its files. The entry record itself still holds the full file list, so /api/torrents looks healthy. PROPFIND with Depth: 1 on that folder returns no children, and every GET of a file it lists returns 404.
The literal complaint in #373 is fixed: all transfers show up now. But some of the folders that show up are empty, so the content is still not reachable. On my box this left 94 library symlinks dead, and the built-in repair reported the entries as healthy.
What actually breaks
The problem is the name index (items.db), not the provider and not the mount.
Two entries can render the same folder name:
An arr grabs a release. The entry is stored under the magnet infohash H1. The name index gets one record per file in folder F, each tagged with H1.
On a later sync, H1 is no longer on the remote. detectTorrentChanges removes the premiumize placement, the entry has no placements left, and it is deleted.
Storage.Delete calls removeFromEntryItem, which deletes every file record in F tagged H1. That empties the item, so the whole folder is deleted from the name index — even though entry H2 still renders F.
After that the two sides disagree:
Folder listings are built from entry metadata (ForEachMeta), so F is still listed in __all__.
Folder children come from GetEntryItem(F) in getTorrentChildren, which now returns "key not found", so the folder has zero children and every file 404s.
Nothing rebuilds the index on its own, because it is only written when an entry is written. So the folder stays empty until that entry happens to be written again.
Repair does not catch it either: repair asks the provider whether the files exist, and they do. It never compares the provider against what the WebDAV tree actually serves.
In code this is provider-independent, but in practice only Premiumize hits it, because it is the only provider that re-keys the same release. Every other provider reports a real infohash (realdebrid.got.Hash, debrid_link.got.HashString, alldebrid.gomagnet.Hash, torbox.godata.Hash).
Evidence
Same entry, two views:
Probe (curl straight at :8282, no rclone or FUSE in the path)
Sync-found PM entry
Grab-made PM entry
Any RD entry
Listed in PROPFIND /webdav/__all__/ Depth 1
yes
yes
yes
PROPFIND <entry>/ Depth 0
207, 84 bytes
207
207
PROPFIND <entry>/ Depth 1
0 children
24 hrefs
files listed
GET <entry>/<file it lists in /api/torrents>
404
200 / 206
200 / 206
Files in the entry record
24
23
fine
Repair on the same box, with every broken entry in the candidate set:
Provider side was fine throughout: transfer/list returned all 9 transfers as finished, and nothing was deleted.
How to check a database for this
Compare the folder names in the entries store metadata with the keys in the items store. Any folder name that has a live entry but no item record is in this state. On my box that was exactly 7 folders, all Premiumize, and it matched the broken folders one for one.
Repro
Run Decypharr with a Premiumize provider.
Grab a release through an arr so the entry is created from the magnet.
Let a later sync pick the same transfer up under its synthetic key, and let the sync after that drop the grab-made entry.
PROPFIND the folder: it is listed, and it has no children.
Deleting an entry rebuilds the name index from the entries that are still live, and only removes the folder when no entry maps to it any more.
Startup runs the same rebuild once over the database, so installs that are already in this state recover without waiting for a write.
Both scans read entry metadata only, so a healthy database costs no extra disk reads.
I have been running this on my own box since today: startup logged Rebuilt folders missing from the name index count=7, the folder that returned 84 bytes now returns 24 files, a ranged GET returns 206 with data, and the dead symlink count went from 94 to 0. It also survived a full sync afterwards.
Follow-up to #373.
Summary
On
beta, a Premiumize entry that was found by sync is listed as a folder over WebDAV but serves none of its files. The entry record itself still holds the full file list, so/api/torrentslooks healthy.PROPFINDwithDepth: 1on that folder returns no children, and everyGETof a file it lists returns 404.The literal complaint in #373 is fixed: all transfers show up now. But some of the folders that show up are empty, so the content is still not reachable. On my box this left 94 library symlinks dead, and the built-in repair reported the entries as healthy.
What actually breaks
The problem is the name index (
items.db), not the provider and not the mount.Two entries can render the same folder name:
H1. The name index gets one record per file in folderF, each tagged withH1.transfer/listcarries no infohash, sobetaderives a synthetic keyH2(6639571, the Premiumize: sync mounts 1 of N torrents and /torrents/add rejects uncached, while direct API calls work #373 fix). That is a second entry, with the same name, so the same folderF.H1is no longer on the remote.detectTorrentChangesremoves the premiumize placement, the entry has no placements left, and it is deleted.Storage.DeletecallsremoveFromEntryItem, which deletes every file record inFtaggedH1. That empties the item, so the whole folder is deleted from the name index — even though entryH2still rendersF.After that the two sides disagree:
ForEachMeta), soFis still listed in__all__.GetEntryItem(F)ingetTorrentChildren, which now returns "key not found", so the folder has zero children and every file 404s.Nothing rebuilds the index on its own, because it is only written when an entry is written. So the folder stays empty until that entry happens to be written again.
Repair does not catch it either: repair asks the provider whether the files exist, and they do. It never compares the provider against what the WebDAV tree actually serves.
In code this is provider-independent, but in practice only Premiumize hits it, because it is the only provider that re-keys the same release. Every other provider reports a real infohash (
realdebrid.got.Hash,debrid_link.got.HashString,alldebrid.gomagnet.Hash,torbox.godata.Hash).Evidence
Same entry, two views:
:8282, no rclone or FUSE in the path)PROPFIND /webdav/__all__/Depth 1PROPFIND <entry>/Depth 0PROPFIND <entry>/Depth 1GET <entry>/<file it lists in /api/torrents>Repair on the same box, with every broken entry in the candidate set:
130 of 131 healthy while 94 symlinks were dead.
Provider side was fine throughout:
transfer/listreturned all 9 transfers as finished, and nothing was deleted.How to check a database for this
Compare the folder names in the entries store metadata with the keys in the items store. Any folder name that has a live entry but no item record is in this state. On my box that was exactly 7 folders, all Premiumize, and it matched the broken folders one for one.
Repro
PROPFINDthe folder: it is listed, and it has no children.Fix
PR: #424
Two parts:
Both scans read entry metadata only, so a healthy database costs no extra disk reads.
I have been running this on my own box since today: startup logged
Rebuilt folders missing from the name index count=7, the folder that returned 84 bytes now returns 24 files, a rangedGETreturns 206 with data, and the dead symlink count went from 94 to 0. It also survived a full sync afterwards.Environment
ghcr.io/sirrobot01/decypharr@sha256:84d31557fddbe8200ba9bf433210f929b4777cf2c23a947922715fa2442a7402, reportsv2.5.1-betarealdebrid+premiumize, noselected_debridmount.type: "none", external rclone againsthttp://127.0.0.1:8282/webdav