J’ai récemment joué avec Composer pour gérer les dépendances d’un plugin WordPress, et il faut reconnaître que l’outil simplifie énormément la gestion du code tiers.
Lors d’un changement de Mac, après import de mes anciennes données sur une nouvelle machine, j’ai obtenu ce message d’erreur :
Composer: file_put_contents(./composer.json): failed to open stream: Permission deniedLangage du code : HTTP (http)
Cette erreur signifie que Composer essaie d’écrire dans composer.json, ou dans le dossier courant, mais que l’utilisateur qui exécute la commande n’a pas les droits nécessaires.
Le problème peut venir du dossier du projet, du fichier composer.json, du cache Composer, du dossier global Composer, ou d’un ancien usage de sudo composer qui a laissé des fichiers appartenant à root.
Comprendre l’erreur
Le message important est :
failed to open stream: Permission denied
Composer n’arrive pas à écrire dans le fichier demandé. Dans l’exemple :
file_put_contents(./composer.json)
Composer tente d’écrire dans composer.json, dans le dossier courant.
Cela arrive souvent après :
- une migration de Mac ou de PC ;
- une restauration depuis une sauvegarde ;
- un changement d’utilisateur système ;
- une commande Composer lancée avec
sudo; - un projet copié depuis un autre compte ;
- un dossier synchronisé via Dropbox, iCloud, NAS ou disque externe ;
- un projet créé dans un dossier appartenant à
rootou à un autre utilisateur.
Donc avant de corriger au marteau, on vérifie exactement quel dossier pose problème. Le marteau marche, certes, mais il a une mauvaise finesse de diagnostic.
Première vérification : suis-je dans le bon dossier ?
Commencez par vérifier le dossier courant :
pwd
Puis listez les droits du dossier et du fichier composer.json s’il existe :
ls -ld .
ls -l composer.json composer.lock 2>/dev/nullLangage du code : JavaScript (javascript)
Vous devez voir votre utilisateur comme propriétaire, par exemple :
drwxr-xr-x 12 matt staff 384 6 mai 10:42 .
-rw-r--r-- 1 matt staff 842 6 mai 10:42 composer.jsonLangage du code : CSS (css)
Si vous voyez root ou un ancien utilisateur, Composer ne pourra pas forcément écrire dans le projet.
Correction la plus fréquente : reprendre possession du dossier projet
Si le dossier du projet appartient à un autre utilisateur, corrigez uniquement ce dossier.
Depuis le dossier parent du projet :
sudo chown -R "$USER" mon-projetLangage du code : JavaScript (javascript)
Ou depuis le dossier du projet lui-même :
sudo chown -R "$USER" .Langage du code : JavaScript (javascript)
Sur macOS, on peut aussi préciser le groupe courant :
sudo chown -R "$USER":staff .Langage du code : JavaScript (javascript)
Sur Linux, le groupe porte souvent le même nom que l’utilisateur :
sudo chown -R "$USER":"$USER" .Langage du code : JavaScript (javascript)
Ensuite, relancez la commande Composer :
Vos mises à jour vous font peur ?
PHP 8.x qui casse un plugin, un thème qui n'est plus maintenu, une mise à jour de WooCommerce qui change tout — je gère les montées de version proprement, avec environnement de staging et rollback prévu.
Mettons votre stack à jour sans risque →composer install
ou :
composer require vendor/packageLangage du code : JavaScript (javascript)
Éviter la mauvaise correction : chown -R $USER ~
Dans l’ancienne version de cet article, je proposais :
sudo chown -R $USER ~/.composer/Langage du code : JavaScript (javascript)
Cette commande peut encore être utile si le problème vient vraiment du dossier Composer global. Mais elle ne corrige pas un projet dont le dossier courant appartient à root.
Évitez surtout les corrections trop larges du type :
sudo chown -R "$USER" ~Langage du code : JavaScript (javascript)
C’est brutal, lent, et parfois dangereux. Votre dossier personnel peut contenir des fichiers qui doivent appartenir à d’autres utilisateurs ou avoir des droits spécifiques. Corrigez le dossier exact qui pose problème, pas tout le royaume.
Vérifier le dossier global de Composer
Composer utilise un dossier global, souvent appelé COMPOSER_HOME, pour stocker sa configuration globale, ses plugins et certains fichiers liés à l’utilisateur.
Pour le localiser :
composer config --global homeLangage du code : PHP (php)
Selon votre système, il peut s’agir de :
~/.composer
~/.config/composer
/Users/votre-utilisateur/.composer
/Users/votre-utilisateur/.config/composer
Composer documente notamment COMPOSER_HOME comme le chemin utilisé pour stocker des éléments globaux comme config.json, et documente aussi les chemins de cache par défaut selon le système. Composer CLI : COMPOSER_HOME
Vérifiez les droits :
composer_home="$(composer config --global home)"
ls -ld "$composer_home"Langage du code : JavaScript (javascript)
Si ce dossier appartient à root, corrigez-le :
sudo chown -R "$USER" "$composer_home"Langage du code : JavaScript (javascript)
Sur Linux, avec le groupe utilisateur :
sudo chown -R "$USER":"$USER" "$composer_home"Langage du code : JavaScript (javascript)
Vérifier le cache Composer
L’erreur peut aussi venir du cache Composer, surtout si vous avez déjà lancé Composer avec sudo.
Pour connaître le chemin du cache :
composer config cache-dir
Composer documente cache-dir comme le dossier qui stocke les caches utilisés par Composer. Sur macOS, le cache se trouve par défaut dans /Users/<user>/Library/Caches/composer, et sur les systèmes Unix suivant XDG, dans $XDG_CACHE_HOME/composer. Composer config : cache-dir
Vérifiez les droits :
cache_dir="$(composer config cache-dir)"
ls -ld "$cache_dir"Langage du code : JavaScript (javascript)
Corrigez si nécessaire :
sudo chown -R "$USER" "$cache_dir"Langage du code : JavaScript (javascript)
Ou videz simplement le cache :
composer clear-cache
Ne pas lancer Composer avec sudo
Le piège classique consiste à corriger l’erreur ainsi :
sudo composer install
Oui, cela peut “marcher”. Mais cela crée souvent de nouveaux fichiers appartenant à root dans votre projet ou dans le cache Composer, et vous retrouvez le même problème plus tard.
Composer recommande fortement d’éviter d’exécuter Composer en super-utilisateur/root, car les plugins et scripts Composer peuvent exécuter du code tiers avec les droits de l’utilisateur qui lance la commande. Composer FAQ : exécuter Composer en root
Donc, en local ou sur un serveur classique, utilisez Composer avec votre utilisateur normal :
composer install
composer update
composer require vendor/packageLangage du code : JavaScript (javascript)
Réservez sudo aux opérations système : installer Composer globalement, déplacer un binaire dans /usr/local/bin, installer des paquets APT, etc.
Corriger les dégâts causés par sudo composer
Si vous avez lancé Composer avec sudo, commencez par chercher les fichiers appartenant à root dans le projet :
find . -user root -maxdepth 3 -printLangage du code : PHP (php)
Si vous confirmez que ces fichiers devraient appartenir à votre utilisateur, corrigez le projet :
sudo chown -R "$USER" .Langage du code : JavaScript (javascript)
Sur Linux :
sudo chown -R "$USER":"$USER" .Langage du code : JavaScript (javascript)
Puis corrigez Composer global et son cache si nécessaire :
composer_home="$(composer config --global home)"
cache_dir="$(composer config cache-dir)"
sudo chown -R "$USER" "$composer_home" "$cache_dir"Langage du code : JavaScript (javascript)
Ensuite seulement, relancez Composer sans sudo.
Cas macOS après migration de machine
Après une migration macOS, il arrive que certains dossiers gardent des permissions ou propriétaires incohérents.
Vérifiez votre utilisateur :
whoami
id
Dans le dossier du projet :
ls -ld .
ls -la | head
Si le projet appartient à un ancien utilisateur ou à root :
sudo chown -R "$USER":staff .Langage du code : JavaScript (javascript)
Vérifiez aussi le cache Composer macOS :
ls -ld "$HOME/Library/Caches/composer"Langage du code : JavaScript (javascript)
Et corrigez si nécessaire :
sudo chown -R "$USER":staff "$HOME/Library/Caches/composer"Langage du code : JavaScript (javascript)
Enfin, testez :
composer diagnose
Cas WordPress : thème ou plugin avec Composer
Dans un plugin ou thème WordPress, Composer est souvent utilisé pour charger des dépendances PHP, des outils de build, PHPStan, PHPCS, WPCS, Rector, Freemius SDK, ou une autoload PSR-4.
Dans ce cas, placez-vous à la racine du plugin ou du thème, là où se trouve composer.json :
cd wp-content/plugins/mon-plugin
composer install
Si l’erreur apparaît :
ls -ld .
ls -l composer.json composer.lock vendor 2>/dev/nullLangage du code : JavaScript (javascript)
Puis corrigez seulement le plugin concerné :
sudo chown -R "$USER" wp-content/plugins/mon-pluginLangage du code : JavaScript (javascript)
Sur un serveur de production, je préfère éviter de lancer composer update. On déploie plutôt un composer.lock testé, puis on lance :
composer install --no-dev --optimize-autoloader
composer update change les versions. composer install installe les versions verrouillées. Ce détail évite beaucoup de “mais ça marchait hier”.
Cas serveur web : utilisateur de déploiement et utilisateur PHP
Sur un serveur, évitez de faire appartenir tout le code à www-data si ce n’est pas nécessaire. Une approche courante consiste à avoir :
- un utilisateur de déploiement propriétaire du code ;
- un groupe partagé avec l’utilisateur web ;
- des permissions en lecture pour PHP ;
- des permissions d’écriture limitées aux dossiers qui en ont besoin.
Exemple simple :
sudo chown -R deploy:www-data /home/www/example.com/public_html
sudo find /home/www/example.com/public_html -type d -exec chmod 2755 {} \;
sudo find /home/www/example.com/public_html -type f -exec chmod 0644 {} \;
Pour WordPress, les dossiers d’uploads/cache peuvent nécessiter une stratégie spécifique. Mais Composer, lui, doit être lancé par l’utilisateur qui possède le projet ou par l’utilisateur de déploiement prévu.
Cas Docker
Dans Docker, les erreurs de permissions Composer viennent souvent d’un décalage entre l’utilisateur du conteneur et l’utilisateur de l’hôte.
Exemple :
docker run --rm -v "$PWD":/app -w /app composer installLangage du code : JavaScript (javascript)
Cette commande peut créer des fichiers appartenant à root sur l’hôte selon l’image utilisée.
Une méthode consiste à exécuter Composer avec votre UID/GID :
docker run --rm \
-u "$(id -u):$(id -g)" \
-v "$PWD":/app \
-w /app \
composer installLangage du code : JavaScript (javascript)
Ce n’est pas toujours suffisant selon l’image et le cache, mais cela évite déjà beaucoup de fichiers créés en root dans le projet.
Commandes de diagnostic Composer
Composer fournit quelques commandes utiles pour diagnostiquer l’environnement :
composer diagnose
composer config --list
composer config --global home
composer config cache-dir
composer --versionLangage du code : PHP (php)
Vous pouvez aussi vérifier l’utilisateur courant et les droits :
whoami
id
pwd
ls -ld .
ls -l composer.json composer.lock 2>/dev/nullLangage du code : JavaScript (javascript)
Dans 90 % des cas, ces commandes suffisent à trouver le dossier qui n’appartient pas au bon utilisateur.
Méthode de résolution étape par étape
Voici l’ordre que j’utilise pour corriger cette erreur proprement :
- Vérifier le dossier courant avec
pwd. - Vérifier le propriétaire du dossier avec
ls -ld .. - Vérifier
composer.json,composer.locketvendor. - Corriger uniquement le dossier projet si nécessaire.
- Vérifier
composer config --global home. - Vérifier
composer config cache-dir. - Corriger le cache Composer si nécessaire.
- Relancer Composer sans
sudo. - Exécuter
composer diagnose.
Mémo rapide
# Erreur typique.
Composer: file_put_contents(./composer.json): failed to open stream: Permission denied
# Vérifier où l’on se trouve.
pwd
whoami
id
# Vérifier les droits du projet.
ls -ld .
ls -l composer.json composer.lock vendor 2>/dev/null
# Corriger le dossier projet courant.
sudo chown -R "$USER" .
# macOS.
sudo chown -R "$USER":staff .
# Linux.
sudo chown -R "$USER":"$USER" .
# Trouver le dossier global Composer.
composer config --global home
# Corriger COMPOSER_HOME.
composer_home="$(composer config --global home)"
sudo chown -R "$USER" "$composer_home"
# Trouver le cache Composer.
composer config cache-dir
# Corriger le cache.
cache_dir="$(composer config cache-dir)"
sudo chown -R "$USER" "$cache_dir"
# Vider le cache.
composer clear-cache
# Diagnostic Composer.
composer diagnose
# Relancer sans sudo.
composer installLangage du code : PHP (php)
Conclusion
L’erreur file_put_contents(./composer.json): failed to open stream: Permission denied indique que Composer n’a pas le droit d’écrire dans le fichier ou le dossier ciblé.
La cause la plus fréquente est un problème de propriétaire après migration, restauration, copie de projet, ou exécution de Composer avec sudo.
La correction la plus propre consiste à reprendre possession du dossier concerné :
sudo chown -R "$USER" .Langage du code : JavaScript (javascript)
Si le problème vient du dossier global Composer ou du cache, corrigez-les séparément :
composer_home="$(composer config --global home)"
cache_dir="$(composer config cache-dir)"
sudo chown -R "$USER" "$composer_home" "$cache_dir"Langage du code : JavaScript (javascript)
Enfin, évitez de lancer Composer avec sudo dans vos projets. Cela donne l’impression de résoudre le problème, puis laisse derrière lui des fichiers appartenant à root. Composer est un excellent gestionnaire de dépendances ; inutile de lui donner les clés du royaume pour écrire un fichier JSON.
Marre des agences qui sous-traitent ?
Avec moi, vous parlez directement au développeur qui fait le travail. Pas d'intermédiaire, pas de promesses creuses. Juste du code propre et un interlocuteur joignable.
Travaillons directement ensemble →

