4 points par GN⁺ 2025-08-08 | 1 commentaires | Partager sur WhatsApp
  • Cette liste partage des connaissances maudites acquises lors du développement d'Immich.
  • Elle rassemble des problèmes inattendus découverts dans des environnements logiciels et d'infrastructure variés.
  • Elle mentionne des problèmes par outil et langage, comme les métadonnées EXIF, la gestion des espaces YAML, PostgreSQL, etc.
  • Certains problèmes sont directement liés à la sécurité, à la compatibilité des plateformes et aux dépendances open source.
  • L'accent est mis sur des cas concrets et leurs causes auxquels les développeurs doivent faire attention.

Aperçu

L'équipe de développement d'Immich rend publiques les connaissances maudites qu'elle a acquises au cours du projet et qu'elle ne souhaite plus jamais revoir. Il s'agit d'une liste de pièges et de problèmes inattendus rencontrés en service réel au fil de l'utilisation de divers outils, langages et plateformes pendant le développement et l'exploitation.

Liste des connaissances maudites

  • 4 juin 2025

    • Les Actions de Zitadel sont une fonctionnalité maudite.
    • La fonction de scripting personnalisé fournie par Zitadel est basée sur un moteur JS, mais elle ne prend pas en charge les groupes de capture nommés des expressions régulières, ce qui en limite l'usage.
  • 30 mai 2025

    • Microsoft Entra prend en charge le PKCE, mais ne l'indique pas dans le document de découverte OpenID.
    • Cette absence de documentation provoque un problème où une fonctionnalité existante n'est pas détectée côté client.
  • 5 mai 2025

    • Les informations de taille dans les métadonnées EXIF d'une image peuvent être différentes de la taille réelle de l'image.
    • Cet écart peut générer des erreurs lors des opérations de recadrage et de redimensionnement.
  • 1 avril 2025

    • Le traitement des espaces en YAML se comporte souvent différemment des attentes.
    • Il est sensible au formatage et peut être interprété d'une manière inattendue.
  • 20 septembre 2024

    • Les fichiers cachés de Windows ne s'ouvrent pas avec le drapeau w.
    • Associé à l'option hide dot files de SMB, cela augmente la confusion lors de l'exploration et du traitement des fichiers.
  • 7 août 2024

    • Les scripts Bash peuvent rencontrer des problèmes de retour chariot (CRLF).
    • Lorsque Git convertit automatiquement les LF en CRLF au checkout, cela peut provoquer des erreurs d'exécution.
  • 7 août 2024

    • Dans Cloudflare Workers, fetch applique http par défaut même si https est explicitement indiqué.
    • Cela peut entraîner des problèmes réseau, comme des boucles de redirection.
  • 21 juillet 2024

    • Le partage GPS sur mobile supprime silencieusement les données GPS des images si l'application n'a pas l'autorisation de localisation.
    • Cela affecte la précision des services géolocalisés et la confidentialité.
  • 3 juillet 2024

    • NOTIFY de PostgreSQL ne fonctionne qu'au sein d'une transaction.
    • Lorsqu'il est utilisé avec l'adapter postgres de socket.io, cela déclenche des écritures WAL toutes les 5 secondes, ce qui peut générer une charge.
  • 3 juillet 2024

    • Chaque exécution d'un script npm envoie une requête HTTP vers le registre npm.
    • Les checks de santé via script sont donc inefficaces.
  • 28 juin 2024

    • Certains membres de la communauté JavaScript ont imposé l'ajout de plus de 50 dépendances pour des raisons de rétrocompatibilité.
    • Tous ces paquets sont maintenus par la même personne.
  • 25 juin 2024

    • Les implémentations de bcrypt n'utilisent que les 72 premiers octets d'une chaîne.
    • Les caractères suivants étant ignorés, les mots de passe longs deviennent inefficaces.
  • 31 janvier 2024

    • L'objet Date de JavaScript indexe l'année et le jour à partir de 1, et le mois à partir de 0.
    • C'est une structure facile à confondre.
  • 9 janvier 2024

    • Avant Node.js v20.8, dans un projet CommonJS utilisant l'option --experimental-vm-modules, lorsqu'un module ES charge à nouveau un module CommonJS,
      • un segfault peut provoquer un crash de Node.js.
  • 28 décembre 2023

    • La limite de paramètres de PostgreSQL est de 65 535.
    • Cela crée des limites de performance pour les insertions en masse de jeux de données volumineux.
  • 26 juin 2023

    • Certaines Web API ne sont disponibles que dans des Secure Contexts.
    • Par exemple, l'API Clipboard et similaires ne fonctionnent qu'en https ou sur un environnement localhost.
  • 23 février 2023

    • L'implémentation remove de TypeORM affecte directement la valeur d'entrée.
    • Elle supprime même la propriété id de l'objet source.

Conclusion

Ces connaissances maudites représentent des pièges fréquemment rencontrés dans des contextes réels de développement et d'exploitation de services. Les développeurs gagnent à identifier en amont les contraintes et les problèmes cachés de chaque outil, langage et environnement, afin de faciliter la résolution efficace des incidents et un développement de services plus fiable.

1 commentaires

 
GN⁺ 2025-08-08
Avis de Hacker News
  • J’ai vraiment apprécié ça dès la première fois que je l’ai vu. En regardant ensuite le commit d’exemple (ici), c’est encore mieux passé. Le fait de consigner un « savoir maudit » avec le code qui a résolu le problème est particulièrement intéressant. La première chose qui me vient à l’esprit, c’est que cette fonctionnalité est nécessaire dans tous les projets. Les logs ne servent pas qu’à la catharsis : ils transforment les problèmes pénibles en expériences d’apprentissage positives. En les publiant, on peut aussi se retrouver avec des personnes qui ont rencontré le même souci et ça peut devenir un outil de prévention.

    • Je mets généralement ce type d’informations directement dans le message de commit. Quand quelqu’un lit une ligne de code et pense "Pourquoi cette ligne est écrite comme ça ? On ne peut pas juste faire ___ ?", c’est utile d’avoir l’explication sous la main.
  • J’ai été surpris en voyant la partie : « on ne peut pas binder 65 000 placeholders PostgreSQL dans une seule requête ». À la base, ce n’est pas une très bonne idée, donc blâmer PostgreSQL n’est pas vraiment logique. En lisant les commentaires d’issues GitHub, il semble qu’une approche raisonnable a été prise : refactorer l’ORM pour diviser une grosse requête en plusieurs plus petites. Personnellement, une écriture de 3 000 à 5 000 lignes par requête me paraît adaptée. Quelqu’un a conseillé une méthode où l’on charge d’abord les données dans une table TEMP puis on joint ensuite (en particulier COPY … FROM), ce qui serait plus performant, mais c’est un changement de code trop important, et finalement cette stratégie a été abandonnée. Je pense que c’est une compilation utile de témoignages d’expérience. C’est un bon cas de mise en garde.

    • Je suis d’accord avec l’idée que cette tentative elle-même est une « idée maudite ». Quand on lit toute la liste, on a plutôt l’impression que la « liste maudite » n’est pas tant une impasse ou un piège de conception, qu’une série de leçons apprises à la dure par des développeurs. Même si le niveau de détail varie et que certains items sont encore en cours, elles ont plus de valeur si on les comprend comme des retours d’expérience personnels dans un engineering log.

    • Ça ressemble à la fois à traiter en une seule passe, avec un outil type xargs, tous les noms de fichiers d’un système de fichiers sans caractère NUL. C’est problématique s’il y a des noms spéciaux ou corrompus, ou si la mémoire est insuffisante. Il vaut mieux utiliser des outils comme find -print0 ainsi que parallel -0/xargs -0. Et avec sed, grep, etc., il faut aussi faire attention : sans LC_ALL=C, on peut avoir des erreurs de séquence de caractères multioctets.

    • J’ai personnellement rencontré une erreur de binding de 65 000 en faisant du upsert massif de records avec un ORM. Surtout quand la table a une colonne de type tableau SQL, on doit binder chaque élément inséré, donc le nombre de variables de liaison fluctue. Du coup, même si le nombre de lignes/colonnes semble identique après deux exécutions, le nombre de variables à binder peut changer, créant une situation instable.

    • Une autre stratégie consiste aussi à passer les valeurs comme arguments de tableau (text[], int[], etc.). PostgreSQL gère bien ça. L’opérateur ANY() est un peu plus lent que IN(), mais il permet de regrouper plusieurs IDs dans un seul paramètre. Il est possible que l’ORM ne supporte pas cela.

    • Ça m’a aussi frappé : binder autant de paramètres, c’est clairement une approche maudite. En traitement massif, il faut généralement utiliser COPY. Pour rajouter un autre cas franchement maudit sur Postgres, le nom du prepared statement est silencieusement tronqué à NAMEDATALEN-1 (NAMEDATALEN vaut 64). C’est le cas depuis 2001, et c’était déjà là avant. Les ORM doivent absolument en être conscients. Les humains utilisent rarement un nom de prepared statement de plus de 60 caractères, mais les ORM font exception.

  • L’élément « installer 50 paquets supplémentaires » est vraiment choquant. L’auteur de ce package a sans doute boosté artificiellement les downloads. Quand on pense à la bande passante et à l’espace disque gaspillés à l’échelle mondiale, c’est vraiment dommage. Je me demande s’il ne cherchait pas à se faire un nom.

    • Le mainteneur de ce package pointé comme « connaissance maudite » est un membre de TC39. C’est une personnalité qui a souvent fait polémique dans plusieurs projets JavaScript connus. Des accusations d’un motif financier ont existé autour de certains sujets de polyfill, mais comme les revenus de GitHub Sponsor ou de Tidelift ne sont pas importants, je pense qu’il suit une conviction réelle sur la compatibilité. Au 2025, j’ai un peu changé d’avis à ce sujet. Il assure une maintenance importante de manière continue, et je pense que son rôle de proposer des positions contestées au sein de la communauté est peut-être nécessaire.

    • Cela peut aussi être dû à la réputation ou à un caractère atypique, mais il existe aussi une interprétation extrême : une préparation en amont à une énorme attaque de la chaîne d’approvisionnement logicielle.

    • L’auteur en question est presque certainement ljharb.

  • NTFS Alternate Data Streams (ADS) de Windows permet de cacher un nombre illimité de fichiers dans un fichier existant. macOS crée par défaut, y compris via data fork, xattr et l’indexation Spotlight (md), de nombreux fichiers cachés et temporaires sur tous les volumes amovibles. Solution : mdutil -X /Volumes/path/to/vol Et il y a énormément de télémétries de type opt-out (go, yarn, meilisearch, homebrew, vcpkg, dotnet, Windows, VS Code, Claude Code, macOS, Docker, Splunk, OpenShift, Firefox, Chrome, flutter, etc.), avec des inquiétudes sur la vie privée de partout.

    • Télémétrie opt-out : dans le cas de go, les données de télémétrie sont stockées localement par défaut. Elles peuvent être téléchargées vers telemetry.go.dev uniquement si l’utilisateur l’autorise, et seulement certaines données approuvées. L’activation des envois se fait avec « go telemetry on », la désactivation complète avec « go telemetry off » (voir la documentation).

    • La seule télémétrie vraiment utile est celle en mode opt-out.

  • Pour le signalement « une requête HTTP est envoyée vers le registre npm à chaque exécution d’un script npm », je me demande s’il est réel. Si c’est le cas, ce serait un comportement incohérent pour un gestionnaire de packages.

    • C’est probablement un contrôle de présence de mise à jour npm. Un message de mise à jour peut parfois s’afficher lorsqu’on utilise une version ancienne.

    • C’est probablement pour vérifier les mises à jour ; des bannières de mise à jour s’affichent parfois.

  • Il semble manquer une entrée. La partie sur le traitement de la date et de l’heure dans les métadonnées EXIF date déjà d’un ancien débat. Issue de référence 1, Issue de référence 2, Issue de référence 3

    • Les dates et heures elles-mêmes sont faciles à maudire. Même quand ça fonctionne, le risque de panne existe toujours dans les fonctionnalités associées. C’est encore plus vulnérable si les valeurs incluent des fuseaux horaires ou l’heure d’été.
  • Je pense au document « Madness beyond the gates » sur Hadoop et Kerberos (lien). Ce texte m’a déjà sauvé à plusieurs reprises d’être au bord de la dépression mentale. Je voudrais remercier Steve pour ça. Je n’imagine même pas l’effort qu’il a fallu pour extraire ce savoir maudit.

  • Cette idée de regrouper les connaissances maudites en un seul endroit est excellente. Je comprends aussi bien que ce sont des retours d’expérience qu’on ne peut vivre qu’en allant profondément dans un projet. Je compte créer une telle liste pour chaque projet à venir.

  • L’élément en question n’est pas une connaissance maudite, mais une question de sécurité/confidentialité liée à la gestion des permissions des OS mobiles.

  • Belle idée ! Je me demande si d’autres veulent partager leurs propres connaissances maudites. Dans mon expérience, les noms de fichiers sur macOS sont aussi maudits :

  1. Par défaut, les noms de fichiers sur macOS ne sont pas sensibles à la casse (file.txt et FILE.txt sont équivalents)
  2. Quand macOS stocke un nom en NFC, il peut parfois être converti en NFD.
  • En 1995, lors de la version bêta de Windows 95, j’ai d’abord créé le CDDB. Les noms de pistes des CD audio étaient distribués dans des fichiers .ini, mais le projet s’est arrêté à cause de la limite de taille de 64 Ko des fichiers .ini.

  • C’est exact. Si vous créez un volume APFS ou HFS+ sensible à la casse pour un système ou un volume de données, cela pose inévitablement problème.

  • L’« élément 1 » n’est qu’une configuration par défaut. HFS et APFS ont tous les deux une option sensible à la casse. NTFS fonctionne de manière similaire. Comme ces systèmes de fichiers sont case-retentive, on peut faire :

 $ echo yup > README.txt
 $ cat ReAdMe.TXT
 yup
 $ ls
 README.txt

Le vrai problème est que Steam refuse totalement l’installation sur un système de fichiers case-sensitive, bien que la version Linux existe aussi.