Guide de résolution de problèmes courants. Pour le manuel utilisateur, voir MANUAL.md. Pour l'API REST, voir api/ENDPOINTS.md.
Ce document recense les symptômes les plus fréquents rencontrés en production, leur cause probable et la procédure de résolution. Chaque section référence les chemins de logs et modules concernés.
- Démarrage de l'app
- Probe vidéo (ffprobe / mediainfo)
- APIs externes (TMDb, Jellyfin, Plex, Radarr)
- Performance et scan lent
- Apply / Undo / Conflits
- Réseau & Dashboard distant
- Notifications desktop
- Base de données SQLite
| Fichier | Chemin Windows |
|---|---|
| Log principal (rotation 50 MB × 5) | %LOCALAPPDATA%\CineSort\logs\cinesort.log |
| Crash au démarrage | %LOCALAPPDATA%\CineSort\startup_crash.txt |
| Settings utilisateur | %LOCALAPPDATA%\CineSort\settings.json |
| Backups DB automatiques | %LOCALAPPDATA%\CineSort\backups\ |
| State runs (plans, reports) | %LOCALAPPDATA%\CineSort\runs\<run_id>\ |
| Cache TMDb | %LOCALAPPDATA%\CineSort\tmdb_cache\ |
Astuce : depuis l'app, Aide → Ouvrir le dossier des logs ouvre directement le bon dossier.
- Vérifier :
%LOCALAPPDATA%\CineSort\startup_crash.txt(généré parapp.py:_write_crash_dump()). - Causes courantes :
- DLL Windows manquante (Visual C++ Redistributable, WebView2).
- Antivirus en quarantaine sur
CineSort.exe(faux positif PyInstaller onefile). ffprobe.exeintrouvable mais critique pour la suite.
- Solutions :
- Whitelister
CineSort.exedans l'antivirus puis re-télécharger depuis la GitHub Release officielle. - Installer Microsoft Edge WebView2 Runtime (requis par pywebview).
- Lancer
CineSort.exe --devune fois pour voir la stacktrace en console.
- Whitelister
- Causes :
- Migration DB en cours sur une grosse base (centaines de runs, milliers de quality_reports).
- Backup DB automatique avant migration (V2-G) sur un disque lent.
- Reconciliation des
pending_movesau boot (apply interrompu lors d'une session précédente).
- Logs à consulter :
cinesort.logau niveauINFO, cherchermigration_manageroureconcile_at_boot. - Solution : laisser terminer (un message « Vous pouvez fermer cette fenêtre » apparaît si la migration dure plus de 60 s). Si l'app reste bloquée 5 min, voir section 8.
- Causes :
.execorrompu (interruption du téléchargement).- Faux positif AV en quarantaine silencieuse.
- Manque de privilèges sur
%LOCALAPPDATA%.
- Solutions :
- Re-télécharger depuis la source officielle, vérifier le hash SHA256 si fourni.
- Lancer en mode console :
cmd.exe→cd %USERPROFILE%\Downloads→CineSort.exe(les erreurs Python remontent dans la console). - Tester un lancement « Exécuter en tant qu'administrateur » (juste pour diagnostic).
- Cause : aucun de
ffprobe.exe/mediainfo.exedétecté dans le PATH ni danstools/. - Logs :
cinesort.log→tools_managerouprobe_support: ffmpeg introuvable. - Solutions :
- Réglages → Outils vidéo → Installer/Détecter lance
auto_install.pyqui télécharge une build statique ffmpeg dans%LOCALAPPDATA%\CineSort\tools\. - Manuel : poser
ffprobe.exedans le dossiertools/à côté deCineSort.exe. - Sans probe, le scoring qualité reste à 0 mais le scan / rename fonctionne.
- Réglages → Outils vidéo → Installer/Détecter lance
- Causes :
- Fichier corrompu (header invalide, file integrity check
magic bytes). - Container exotique non supporté (
.evo,.mpls,.3gp). - Timeout dépassé (
PROBE_TIMEOUT_Sdanscinesort/infra/probe/constants.py).
- Fichier corrompu (header invalide, file integrity check
- Logs :
cinesort.log→ProbeService.probe failed: ... timeout=.... - Solutions :
- L'app injecte le warning
integrity_probe_failedvisible dans la validation. Vérifier le fichier dans VLC : si VLC ne lit pas non plus, le fichier est corrompu. - Augmenter le timeout via
Réglages → Analyse vidéo → Timeout probe(limite raisonnable : 60 s). - Pour un container exotique : convertir en MKV avec
ffmpeg -i input.evo -c copy output.mkv.
- L'app injecte le warning
- Causes :
- Probe désactivée ou outils absents (cf. supra).
- Cache
probe_cachecorrompu. - Interruption du scan avant la phase scoring.
- Solutions :
- Réglages → Analyse vidéo → Vider le cache (bouton « Réinitialiser le cache probe »).
- Relancer un scan complet (les hits incrémental peuvent ignorer les films manquants → cocher « Forcer rescan » sur la vue Processing).
- Cause : clé vide, expirée ou tapée avec espaces.
- Logs :
tmdb_client.py→TMDb 401 UnauthorizedouTMDb 404 not found. - Solution : régénérer une clé sur https://www.themoviedb.org/settings/api, la coller dans Réglages → TMDb → Clé API, cliquer Tester la connexion.
- Causes : titre trop déformé (release scene), film amateur absent de TMDb, accents perdus.
- Solutions :
- L'app retire l'édition (
-EXTENDED-DC.mkv→Film) avant la recherche TMDb (cf.edition_helpers.py). - Renseigner un
.nfoKodi avec<tmdbid>à côté du film : la recherche est court-circuitée. - Fallback : pose IMDb ID dans le
.nfo→find_by_imdb_id()interroge l'endpoint/find.
- L'app retire l'édition (
- Cause : 40 requêtes / 10 s par IP côté TMDb.
- Logs :
TMDb HTTP 429. - Solution :
make_session_with_retry(urllib3) gère le backoff automatique. Si le scan reste bloqué, vérifier qu'aucune autre app TMDb ne tourne en parallèle sur la même IP.
- Causes : URL incorrecte (oublier
http://ou:8096), serveur arrêté, clé API invalide. - Logs :
jellyfin_client.py→Jellyfin connection failed: .... - Solutions :
- Tester l'URL dans le navigateur :
http://serveur:8096/web/. - Régénérer une clé API : Tableau de bord Jellyfin → API Keys → Nouvelle clé.
- Réglages → Jellyfin → Tester la connexion affiche le code HTTP exact.
- Tester l'URL dans le navigateur :
- Cause : Jellyfin n'a pas re-indexé assez vite après le rename (latence file system).
- Logs :
jellyfin_sync.py→restore: still waiting for re-index, retry n/5. - Solution : v7.6.0 retry x5 avec backoff exponentiel (jusqu'à 135 s total). Si le restore
échoue tout de même, le snapshot reste dans
<run_dir>/jellyfin_watched_snapshot.jsonet peut être rejoué.
- Solution : utiliser Jellyfin → Vérifier la cohérence (endpoint
get_jellyfin_sync_report). Le rapport listemissing_in_jellyfin(à ajouter manuellement) etghost_in_jellyfin(entrées Jellyfin sans fichier source).
- Cause : token expiré ou pas le bon (token de compte vs token de serveur).
- Solution : récupérer le token via plex.tv account → XML view et le coller dans Réglages → Plex → Token.
- Cause : la section Plex n'est pas de type
movie. - Logs :
plex_client.py→get_libraries("movie")retourne[]. - Solution : vérifier le type de la bibliothèque Plex (Films vs Séries vs Photos).
- Cause : Radarr v2 (déprécié) ou clé API
X-Api-Keyvide. - Logs :
radarr_client.py→Radarr 404 /api/v3/system/status. - Solution : mettre à jour Radarr en v4+, copier la clé depuis Settings → General → Security.
- Cause : Radarr ne connaît pas le film (pas dans sa bibliothèque ou tmdb_id différent).
- Solution :
build_radarr_report()matche en 3 niveaux (tmdb_id → chemin → titre+année). Si tous échouent, ajouter le film manuellement dans Radarr ou vérifier letmdb_iddans le.nfo.
- Causes :
- Bibliothèque > 5000 films sur HDD lent (read random ~50 MB/s).
- Analyse perceptuelle activée pour tous les films (très coûteuse, 2-5 min/film).
- Pas de cache incremental (premier scan, nouveau dossier).
- Logs :
cinesort.log→plan_support: scanned X files in Y s. - Solutions :
- L'analyse perceptuelle est désactivée par défaut. Activable à la demande sur un film via l'inspecteur. Pour la batcher : Qualité → Analyser perceptuel (sélection).
- Le cache incremental v2 (couche dossier + couche vidéo) accélère les scans suivants : un scan complet sans modif = quasi 0 s.
- Parallélisation perceptuelle prévue v7.7.0 (V5-02 multiprocessing.Pool, V5-04 probe ThreadPoolExecutor).
- Cause : > 2000 films rendus en une seule passe (no virtualization).
- Solution : virtualisation tabulaire (windowing 30-50 rows) prévue v7.7.0 (V5-01). En attendant, utiliser les filtres tier / résolution pour réduire la liste affichée.
- Cause : event listener leaks (1-3 MB/8 h, accepté).
- Solution : redémarrer l'app. Les memory leaks majeurs ont été corrigés v7.7.0 V2-05 (notification-center, journal-polling, router).
- Cause :
shutil.moveinterrompu, journal SQLite incomplet. - Mécanisme : pattern WAL
apply_pending_moves(migration 019). Chaque move est écrit dans le journal AVANT exécution, et supprimé APRÈS confirmation. - Solution : au prochain boot,
reconcile_at_boot()(move_reconciliation.py) inspecte les pending_moves et leur attribue un verdict :completed/rolled_back/duplicated/lost. Une notification UI est levée s'il reste des conflits à trancher. - Logs :
cinesort.log→move_reconciliation: verdict=....
- Cause : l'utilisateur a déplacé / renommé le fichier hors de l'app entre apply et undo.
- Solution : les conflits sont placés dans
<root>\_review\_undo_conflicts\avec le détail (chemin attendu vs réalité). Restaurer manuellement depuis cette zone. - Logs :
apply_support.py→_execute_undo_ops: conflict for row_id=....
- Cause : 2 films distincts ciblent le même dossier de destination (collision).
- Mécanisme :
_check_file_collisions(duplicate_support.py) détecte ces cas avant apply. Le dashboard affiche un encart « Conflits détectés » dans la phase Validation. - Solution : utiliser Comparer la qualité (vue côte-à-côte avec 7 critères + score
perceptuel V2 + sous-titres FR), garder le meilleur, déplacer l'autre vers
<root>\_duplicates_identical\ou_review/_conflicts/.
- Cause : permissions insuffisantes sur le dossier racine (NAS read-only, partition full).
- Pré-check :
disk_space_check.pyrefuse l'apply si l'espace libre <max(somme*1.10, 100MB). - Solution : vérifier les ACL Windows (
Sécurité → Modifier) ou monter le NAS en R/W.
- Causes possibles :
- Token absent dans l'URL ou expiré (le dashboard utilise sessionStorage par défaut).
- Port
8642bloqué par le firewall Windows. - Token < 32 caractères + bind
0.0.0.0→ rétrogradation automatique vers127.0.0.1(sécurité).
- Logs :
rest_server.py→LAN bind demoted to 127.0.0.1: token too short. - Solutions :
- Générer un token long (>= 32 caractères) dans Réglages → API REST → Token.
- Ouvrir le port :
Pare-feu Windows → Règles entrantes → Nouvelle règle → Port TCP 8642. - Récupérer l'URL avec QR code dans Réglages → API REST → Lien dashboard.
- Causes : token incorrect, token modifié sans re-login dans le dashboard.
- Logs :
cinesort.log→REST 401 invalid token from <ip>. - Solutions :
- Re-saisir le token dans le dashboard (Login).
- Si suspect d'attaque : changer le token dans Réglages, redémarrer le serveur REST à chaud (bouton « Redémarrer API REST »).
- Cause :
_RateLimiter— 5 échecs 401 par IP en 60 s déclenchent un blocage 60 s. - Logs :
rest_server.py→REST 429 rate limit <ip>. - Solution : attendre 60 s, vérifier le token, ne pas tester en boucle. Le rate-limiter est per-IP : un autre poste sur le même réseau n'est pas affecté.
- Cause : certificats
cert.pem/key.pemintrouvables → fallback HTTP automatique. - Logs :
rest_server.py→HTTPS disabled: cert not found, fallback HTTP. - Solution : générer un cert auto-signé :
puis renseigner les chemins absolus dans Réglages → API REST → HTTPS.
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=CineSort"
- Vérifications :
- Réglages → Notifications → Activer les notifications est coché.
- Le toggle par type (
scan_done,apply_done,undo_done,error) est activé pour l'évènement attendu. - Windows → Paramètres → Système → Notifications : CineSort n'est pas en mode silencieux (Focus assist actif sans whitelist).
- Comportement attendu : si la fenêtre CineSort a le focus (
document.hasFocus() === true), aucun toast n'est émis (intentionnel, évite le bruit). - Logs :
notify_service.py→notify queued: scan_donepuisnotify dispatched. - Diagnostic : si le log montre
notify queuedmais pas de toast, le drain_timer du main thread est peut-être bloqué (rare). Redémarrer l'app.
- Cause :
NotifyService.set_center_hook()mirror inconditionnel +emit_from_insights()sans dédup. - Solution : fixé v7.6.0 — dédup par
(code, source)dansNotificationStore. Si le bug ressurgit, vider le store via API → clear_notifications.
- Cause : la base SQLite est posée dans un dossier synchronisé par OneDrive, Dropbox, Google
Drive, iCloud Drive, Box, pCloud ou Mega. CineSort utilise SQLite en mode WAL : trois
fichiers cohabitent (
cinesort.sqlite,cinesort.sqlite-wal,cinesort.sqlite-shm). Le moteur de synchronisation cloud peut copier le.sqlitealors que des pages sont encore dans le-walou-shm, ce qui produit une corruption silencieuse détectée plus tard parPRAGMA integrity_check(cf. symptôme suivant). - Détection : au boot,
sqlite_store.py:_detect_cloud_sync_folder()matche case-insensitive les marqueursOneDrive,Dropbox,GoogleDrive,Google Drive,iCloudDrive,iCloud Drive,Box,pCloud,Megadans le chemin. Si trouvé →logger.warning(...). - Logs :
cinesort.log→WARNING DB SQLite detectee dans un dossier de synchronisation cloud (<provider>). Chemin: .... - Solutions (par ordre de préférence) :
- Déplacer la DB hors du dossier synchronisé vers l'emplacement par défaut
%LOCALAPPDATA%\CineSort\db\cinesort.sqlite(jamais synchronisé) :- Fermer CineSort proprement.
- Copier
cinesort.sqlite,cinesort.sqlite-wal,cinesort.sqlite-shmet le dossierbackups/vers le nouveau chemin. - Mettre à jour
state_dirdanssettings.jsonou reset au défaut.
- Exclure les fichiers SQLite de la synchronisation (si déplacement impossible) :
- OneDrive :
Get-ChildItem <db_dir>\*.sqlite*, <db_dir>\backups | ForEach-Object { attrib +U $_.FullName }(marqueToujours conserver sur cet appareil), puis ajouter les patterns dans Settings OneDrive → Sauvegarde → Choisir les dossiers. - Dropbox : clic droit sur
cinesort.sqlite→ Smart Sync → Local only + ignorer les patterns.sqlite-wal/.sqlite-shmviadropbox.py exclude add. - Google Drive : exclure le dossier complet via Drive for Desktop → Préférences → Google Drive → Dossiers de mon ordinateur.
- OneDrive :
- Si la corruption a déjà eu lieu : l'app tente un auto-restore depuis le backup le plus
récent au boot suivant. Sinon : voir
Symptôme : « DB integrity check FAILED »ci-dessous.
- Déplacer la DB hors du dossier synchronisé vers l'emplacement par défaut
- Cause : corruption SQLite (coupure courant pendant écriture WAL, secteur disque défectueux).
- Mécanisme :
PRAGMA integrity_checkexécuté au boot (V2-G). Si KO → tentative de restore automatique depuis le backup le plus récent. - Logs :
sqlite_store.py→integrity check FAILED, attempting auto-restore from <path>. - Solution :
- Vérifier
%LOCALAPPDATA%\CineSort\backups\(5 backups gardés en rotation). - L'app restaure automatiquement le backup le plus récent. Les runs/scans postérieurs au backup sont perdus, mais les fichiers vidéo physiques ne sont pas touchés.
- En dernier recours : supprimer
data.db(etdata.db-wal,data.db-shm) → l'app crée une base vierge au prochain boot. Settings sont préservés (fichiersettings.jsonséparé).
- Vérifier
- Cause : ALTER TABLE sur une colonne déjà présente, incompatibilité de schéma.
- Mécanisme : SAVEPOINT avec garde idempotence (catch « duplicate column » / « already exists »). Backup auto déclenché AVANT chaque série de migrations.
- Logs :
migration_manager→migration NNN failed: ...etrestoring from backup. - Solution : copier
data.dbailleurs pour analyse, restaurer le backup pré-migration depuisbackups/, ouvrir une issue GitHub avec les logs.
- Cause : autre processus tient une transaction longue (rare avec WAL + busy_timeout=5000ms).
- Solution : fermer toute autre instance CineSort. Si persistant, redémarrer Windows pour libérer les handles.
- Manuel utilisateur : MANUAL.md — tutoriel pas-à-pas + glossaire + FAQ.
- API REST : api/ENDPOINTS.md — référence des 98 endpoints.
- Architecture : architecture.mmd — diagrammes Mermaid des modules.
- Signaler un bug : Aide → Exporter le diagnostic (zip avec logs scrubbés sans clés API), joindre à une issue GitHub.