| 1 |
# Troubleshooting — audiofiles |
| 2 |
|
| 3 |
## Analysis Pipeline Stalls |
| 4 |
|
| 5 |
**Symptoms:** Analysis batch stuck at a percentage, no progress events. |
| 6 |
|
| 7 |
### Decision Tree |
| 8 |
|
| 9 |
1. **Analysis shows error for specific sample?** |
| 10 |
- "Probe failed" → Unsupported or corrupted audio format. Convert to WAV/MP3 in Audacity. |
| 11 |
- "No audio track" → File has no playable audio stream. |
| 12 |
- "Decoder failed" → Codec not supported by Symphonia. Convert to WAV. |
| 13 |
- "No audio data" → File decoded to zero samples (silent or truncated). |
| 14 |
|
| 15 |
2. **Batch stuck with no error?** |
| 16 |
- Worker thread may be stuck on a very large file |
| 17 |
- Cancel the batch (UI cancel button sends `WorkerCommand::Cancel` + sets `AtomicBool`) |
| 18 |
- Cancel takes effect after the current sample finishes processing |
| 19 |
- If cancel doesn't work in 30s, quit and restart app |
| 20 |
|
| 21 |
3. **Partial results (some fields null)?** |
| 22 |
- `smart_skip` enabled: BPM/key/loop intentionally skipped for non-rhythmic/non-pitched samples (drums, ambience, textures) |
| 23 |
- If unexpected: disable `smart_skip` in analysis config and re-analyze |
| 24 |
|
| 25 |
**WAV fallback:** WAV files that fail the Symphonia probe automatically fall back to the `hound` library. |
| 26 |
|
| 27 |
**Analysis cap:** By default, expensive analyses (STFT, BPM, key) process only the first 30 seconds (`max_analysis_seconds`). Loudness and fingerprint always use the full signal. |
| 28 |
|
| 29 |
## Content-Addressed Storage Corruption |
| 30 |
|
| 31 |
**Symptoms:** "Sample not found" errors, files inaccessible. |
| 32 |
|
| 33 |
**Storage model:** Files stored as `{sha256-hash}.{ext}` in flat directory. Hash IS the primary key. |
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
| "Sample not found: {hash}" | File missing from disk or DB | Check if file exists: `ls ~/.config/audiofiles/samples/{hash}.*`. If missing, re-import from original source. | |
| 38 |
| "Invalid hash: expected 64 lowercase hex chars" | DB corruption (hash field modified) | Find bad rows: `SELECT hash FROM samples WHERE LENGTH(hash) != 64`, delete them | |
| 39 |
| "Cannot import zero-byte file" | Empty file | Skip — only valid audio files with content can be imported | |
| 40 |
| Hash mismatch (file changed on disk) | Disk corruption or manual file edit | Delete corrupted file, remove DB row, re-import original | |
| 41 |
|
| 42 |
**Verify storage integrity:** |
| 43 |
```bash |
| 44 |
# Count files on disk vs DB |
| 45 |
ls ~/.config/audiofiles/samples/ | wc -l |
| 46 |
sqlite3 ~/.config/audiofiles/audiofiles.db "SELECT COUNT(*) FROM samples" |
| 47 |
# Numbers should match (approximately — cloud_only samples have no local file) |
| 48 |
``` |
| 49 |
|
| 50 |
## VFS Inconsistencies |
| 51 |
|
| 52 |
**Symptoms:** Files disappear from browser, "node not found" errors, duplicate names. |
| 53 |
|
| 54 |
|
| 55 |
|
| 56 |
| "Node not found: {id}" | Node deleted or cross-VFS reference | Refresh view (navigate away and back) | |
| 57 |
| "VFS not found: {id}" | VFS deleted | Create new VFS or check DB | |
| 58 |
| "Name conflict: {name}" | Duplicate name at same directory level | Rename one of the duplicates | |
| 59 |
| "Invalid node name" | Contains `/`, `\`, null bytes, or is `.`/`..` | Use standard filenames | |
| 60 |
| "Move would create circular parent reference" | Moving node under its own descendant | Move to a different folder | |
| 61 |
|
| 62 |
**Broken mirror symlinks** (Unix only): If VFS mirror has dead symlinks, re-run mirror sync (idempotent) or delete `~/audiofiles-mirror/` and restart. |
| 63 |
|
| 64 |
**Orphaned samples** (files in store not referenced by any VFS): |
| 65 |
```sql |
| 66 |
SELECT hash FROM samples |
| 67 |
WHERE hash NOT IN (SELECT DISTINCT sample_hash FROM vfs_nodes WHERE sample_hash IS NOT NULL) |
| 68 |
AND hash NOT IN (SELECT DISTINCT sample_hash FROM collection_members WHERE sample_hash IS NOT NULL); |
| 69 |
``` |
| 70 |
|
| 71 |
## Drag-and-Drop Platform Issues |
| 72 |
|
| 73 |
### macOS |
| 74 |
|
| 75 |
|
| 76 |
| Drag doesn't start | App not in foreground, no key window | Click window to focus, try again | |
| 77 |
| Drag ignored on re-attempt | Previous drag still in progress (DRAG_ACTIVE flag) | Wait for first drag to complete | |
| 78 |
|
| 79 |
### Windows |
| 80 |
|
| 81 |
|
| 82 |
| Drag doesn't start | OleInitialize failed or CF_HDROP allocation failed | Restart app. If persistent, check COM initialization. | |
| 83 |
| Drag fails with many files | Temp symlink creation fails | Check `/tmp` permissions and disk space | |
| 84 |
|
| 85 |
### All platforms |
| 86 |
- Drag creates temp symlinks in `/tmp/audiofiles-drag-{pid}/` |
| 87 |
- Name collisions auto-resolved with `(1)`, `(2)` suffixes |
| 88 |
- Large batch drags (100+ files) may be slow — try fewer files |
| 89 |
|
| 90 |
## Database Issues |
| 91 |
|
| 92 |
**Database location:** `~/.config/audiofiles/audiofiles.db` (platform-dependent) |
| 93 |
|
| 94 |
**19 inline migrations** tracked via `PRAGMA user_version`. Run automatically on app startup. |
| 95 |
|
| 96 |
|
| 97 |
|
| 98 |
| App won't start | Migration failed or corrupt DB | Delete DB file and restart (fresh DB). Re-import samples. | |
| 99 |
| "database is locked" | Another process or backup tool | `lsof \| grep audiofiles.db`, close competing process | |
| 100 |
| "FOREIGN KEY constraint failed" | Data corruption (orphaned references) | Fix: `DELETE FROM vfs_nodes WHERE sample_hash NOT IN (SELECT hash FROM samples)` | |
| 101 |
| Slow after large import | WAL file too large | Restart app (checkpoints WAL) or: `sqlite3 audiofiles.db 'PRAGMA wal_checkpoint(TRUNCATE)'` | |
| 102 |
|
| 103 |
**Sync changelog stuck:** |
| 104 |
```sql |
| 105 |
-- Check if applying_remote flag is stuck |
| 106 |
SELECT * FROM sync_state WHERE key='applying_remote'; |
| 107 |
-- If value is '1', fix: |
| 108 |
UPDATE sync_state SET value='0' WHERE key='applying_remote'; |
| 109 |
``` |
| 110 |
|
| 111 |
## Sync Issues |
| 112 |
|
| 113 |
**What syncs:** VFS, samples (metadata), collections (manual and dynamic, via `filter_json`), vfs_nodes, audio_analysis, tags, collection_members, edit_history, user_config (excluding sync-internal keys and `loose_files`). Sync order respects FK relationships. Per migration M018, `sync_changelog.row_id` for sensitive tables is hashed with a per-device `row_id_salt` (never synced); the cleartext canonical key lives in the encrypted `data` field, so a lost salt makes any unpushed changelog rows un-attributable on the next push. |
| 114 |
|
| 115 |
**Blob sync:** Sample audio files sync to cloud storage for VFS entries with `sync_files = true`. The `cloud_only` flag marks samples whose local blobs have been evicted. |
| 116 |
|
| 117 |
|
| 118 |
|
| 119 |
| "Auth error: token expired" | SyncKit token expired | Re-authenticate in sync settings | |
| 120 |
| "Sync client error: connection timeout" | Network down or server unreachable | Check internet, verify server URL | |
| 121 |
| Sample shows "cloud only" but won't download | Upload failed or remote file deleted | Re-trigger sync. If file truly lost, re-import from original. | |
| 122 |
| Changes don't appear on other devices | Push failed or changelog empty | Check `sync_changelog` table for unpushed entries | |
| 123 |
| Changelog growing unbounded | Old entries never cleaned | `DELETE FROM sync_changelog WHERE pushed = 1 AND timestamp < datetime('now', '-30 days')` | |
| 124 |
|
| 125 |
## Diagnostics Checklist |
| 126 |
|
| 127 |
```bash |
| 128 |
# Database integrity |
| 129 |
sqlite3 ~/.config/audiofiles/audiofiles.db "PRAGMA integrity_check" |
| 130 |
|
| 131 |
# Sample count: disk vs DB |
| 132 |
ls ~/.config/audiofiles/samples/ | wc -l |
| 133 |
sqlite3 ~/.config/audiofiles/audiofiles.db "SELECT COUNT(*) FROM samples" |
| 134 |
|
| 135 |
# Pending sync changes |
| 136 |
sqlite3 ~/.config/audiofiles/audiofiles.db "SELECT COUNT(*) FROM sync_changelog WHERE pushed = 0" |
| 137 |
|
| 138 |
# WAL file size (should be <50MB normally) |
| 139 |
ls -lh ~/.config/audiofiles/audiofiles.db-wal |
| 140 |
|
| 141 |
# Broken mirror symlinks (Unix) |
| 142 |
find ~/audiofiles-mirror -type l ! -exec test -e {} \; -print 2>/dev/null |
| 143 |
``` |
| 144 |
|