Engine DJ 5.0.0 — Sync Manager does not create playlist folder structure on USB / SD drives (works on SSD)

i spent some proper time digging into the sqlite databases of my several libraries in their several broken conditions and spent some time trying to infer what was wrong with the new 3.0.2 database schema of engine 5.0.0.

The problem

Since updating to Engine DJ 5.0.0, exporting a library to a USB drive produces a drive with every track on it and zero playlists. The export finishes without any error, the players read the drive normally and the music is all there, but the playlist menu is empty.

The failure propagates. A drive written by the 5.0.0 export still holds your playlists and works on the players and in the desktop app, but if you later use that library as the source of another export (i.e. from another computer using the merged libraries feature that made me fall in love with engine), the new drive gets no playlists either. Once a library has been through the 5.0.0 export, every export derived from it loses the playlists. Downgrading to 4.x does not help, because 4.x cannot correctly process a library that was upgraded to the new database schema. Tracks and all their associated data export fine; only playlists are lost.

What the database shows

Engine DJ is proprietary (what a stupid choice), so I cannot read its code or contribute in any ways other than reverse engineering it, and i’m VERY bad at reverse engineering stuff, so everything that i tried to do was to play with the database files. Luckily enough they were not so stupid to encrypt or obscure the database format, which is luckily an unencrypted collection of SQLite files that simply happen to be overly complicated (overengineering? stratification of ideas over time? no shame in that). The “what” is verified fact and the “why” is deduction, since the export logic itself is not visible to me.

The library sits in Engine Library/Database2/. Playlist data lives only in the main file m.db; the companion files hm.db, sm.db, and stm.db hold history and streaming data and do not matter here. Two tables matter. Playlist holds the folder tree, with title, parentListId for nesting, nextListId for ordering, and two boolean flags named isPersisted and isExplicitlyExported. PlaylistEntity holds which tracks belong to which playlist.

I compared three databases: a healthy library that exports correctly, a 5.0.0-exported copy of that library which fails to export, and a broken export produced from a library in that failed state. The findings:

  1. On broken exports the playlists were never written, which rules out deletion and file corruption. SQLite keeps a per-table insert counter called sqlite_sequence, created on the first insert into a table, and it survives row deletion and database compaction. The broken exports have no counter row for the playlist tables at all, zero reclaimable pages, and a clean integrity check. The export never executed a single playlist insert.

  2. The database schema is identical between the healthy and broken databases, both at version 3.0.2. Whatever breaks the export is a difference in data, since the schema did not change.

  3. The playlist data in the failed library is fully intact. I checked the tree structure and the track memberships down to the linked-list ordering, and everything is valid, which is why players and the desktop app read the library without complaints. The data is present and readable, and the 5.0.0 export simply does not emit it.

  4. The 5.0.0 export zeroes the two flags on the copy it writes. Playlist IDs survive export unchanged, so every source row matches an exported row one to one

For my specific case, 128 playlists lost both flags, going from 1 to 0 while exporting from a healthy library migrated to 3.0.2 but still capable to export to new drives, resulting in a new exported library that was readable but could no longer export to new drives, and none went the other way. Tree structure and edit timestamps were untouched. The flags that survived on the exported copy belong to playlists created or edited on a player after the export, because the player sets them again.

  1. Once the flags are gone, the export writes tracks only. The exact internal condition stays hidden in the proprietary code, and the failed library even kept two flagged root folders without recovering, so the condition is not a simple per-playlist filter. What I can say from experiment is that restoring the flags restores the export.

The fix

I patched two copies of a failed library and ran real 5.0.0 exports against them. The copy with the flags restored exported its playlists again. The second copy had additional changes on top and also worked, so the flags alone are the cause and the fix.

Some context on how I got here and what that means for you. I am a Linux user, and all of this research was done going back and forth between my Linux machine and Windows lab machines, because Engine DJ only runs on Windows and macOS. Denon should seriously consider releasing a native Linux client at this point. The fix itself is only a SQL query against the SQLite file, so any SQLite tool on any operating system can run it. I did my patching on Parrot Security with the sqlite3 command and sqlitebrowser. I have not run the Windows procedure end to end yet, since what I describe for Windows is a reconstruction of what I did on Linux. I will try to reproduce the exact steps on a Windows machine, but until I confirm them, treat that part as untested and take the precautions seriously.

The procedure: quit Engine DJ completely and make a backup copy of m.db. Open the file with your SQLite tool, run the query below, and save the changes. The file to edit is the library you export from. On Windows that is C:\Users\<you>\Music\Engine Library\Database2\m.db and on macOS it is ~/Music/Engine Library/Database2/m.db. For a drive library, edit <drive>/Engine Library/Database2/m.db. But it works even if you apply the changes straight to the database in your USB drives, which makes much more sense since it’s external drives where the but mostly manifest itself.

UPDATE Playlist SET isPersisted = 1, isExplicitlyExported = 1;

Then launch Engine DJ, export again, and check the new drive:

SELECT COUNT(*) FROM Playlist;         -- 0 means the bug is still there, more than 0 means it worked
SELECT COUNT(*) FROM PlaylistEntity;

The query flags every playlist, which is deliberate: it satisfies whatever flag condition the export checks, without needing a healthy reference library to compare against, which most people do not have. The side effect is that every playlist shows as explicitly exported in the software, which was cosmetic in my testing. Seeing so many previously deleted empty playlists popping up again in your collection will bring you back memories :slight_smile:

If a 5.0.0 export already gave you a drive with no playlists, your source library is affected, so apply the fix to it and export again.

Most of us like to export to USB drives and use such USB drives as backups, counting on the old merged libraries feature to kick in and allow old data retrieval. I presume the change in behavior passed silently to the production version because engine devs never took that use case in consideration since engine already offers a backup feature, but unfortunately not everyone lives with only one computer, only one library and only one source of truth for the latest status of the music collection.

Limits of the fix

  • You cannot repair an already broken exported drive in place (the usb with no playlists can’t be fixed, only the library with playlists that can’t export its playlists can be fixed), because the playlists were never written to it. Fix the source library and re-export.
  • The fix holds on the source library, because the export strips the flags only on the copy it writes. Every drive written by 5.0.0 is itself poisoned as a future source, so if you ever export from such a drive, run the fix on it first.
  • Until Denon patches this, check the playlist count on every export before a gig.

i am still curious why several engine versions ago, all of either my cue points or my beat grids were shifted by some milliseconds to the left. now that i managed to recover my library (and even save my girlfriend’s one), i’m left with all my manually adjusted analysis data and all my cue points completely ruined. i can’t recollect when the shift bug was introduced, so i don’t know where to start to fix it, and as i mentioned before, the real value of my collection was not in the tracks and their order in playlist (that’s easy to re-download and restore into any software) but from all the years of metadata adjustment done on them (grid, cue points, saved loops etc).

maybe my adhd will trigger again and i’ll infer a fix from looking at the database, but i really hate SQL and i would love to waste my time doing other means of contributions.

i hope my previous research saves someone else as it saved me today :slight_smile: