Posible solución para NPM - Failed to replace env in config: ${NPM_TOKEN}
Respuesta rápida
npm o yarn han encontrado un fichero .npmrc que referencia una variable de entorno (NPM_TOKEN) que no está definida en tu shell, así que no pueden expandirla. Exporta la variable (export NPM_TOKEN=tu_token) o localiza el .npmrc que la referencia — en la raíz del proyecto o en tu carpeta de usuario — y elimina la entrada obsoleta. Ejecuta la instalación con --verbose para ver exactamente qué ficheros .npmrc se están leyendo.
El propio texto del error te lo dice: Failed to replace env in config: ${NPM_TOKEN}. npm te está avisando de que intentó sustituir un marcador ${...} y no había nada con lo que rellenarlo.
Por qué pasa
Para instalar un paquete privado del registro de GitHub apuntas npm a ese registro y le das un token. El token vive en una variable de entorno para que nunca acabe en el repositorio, y el .npmrc lo referencia por su nombre:
Cuando ejecutas npm install o yarn, npm lee ese fichero y expande cada ${VAR} contra tu entorno actual. Si NPM_TOKEN no está definida en esa shell, no puede reemplazar el marcador y aborta: ese es el error exacto.
Los ficheros .npmrc que npm lee de verdad
Esta es la parte que convierte un arreglo de un minuto en uno de dos horas. npm no lee un único .npmrc; combina varios, y gana el más cercano. Por orden de precedencia:
- Proyecto:
./.npmrc - Usuario:
~/.npmrc(en Windows,C:\Users\<tú>\.npmrc) - Global:
$PREFIX/etc/npmrc - Configuración interna de npm
Así que una línea que añadiste hace meses a tu .npmrc de usuario se aplica a todos los proyectos que instalas, incluso los que no tienen ni idea de qué es NPM_TOKEN. Esa es la razón habitual de que el error aparezca en un repo que nunca configuraste para el registro de GitHub.
Causas habituales, ordenadas
- La variable no está realmente definida en la shell desde la que lanzaste el comando.
- El
.npmrcestá en tu carpeta de usuario, no en el proyecto, y se cuela en instalaciones que no tienen nada que ver. Este fue mi caso: lo había guardado enC:\Users\xabierlameiro\.npmrc, y todos los proyectos heredaban la referencia a${NPM_TOKEN}. - La variable está definida en una app gráfica o en otra pestaña de terminal que no heredó el export.
- En CI, el secreto existe pero nunca se expuso al entorno del paso.
Cómo lo arreglé
Primero lancé la instalación en modo verbose para ver qué ficheros estaba leyendo npm:
yarn install --verbose
El log lista las rutas donde busca el .npmrc, y ahí vi que estaba cogiendo la configuración de mi carpeta de usuario. Lo eliminé de la carpeta de usuario y lo volví a crear en la raíz del proyecto, y el error desapareció.
Si en cambio quieres el token disponible en todas partes, defínela en vez de quitar la referencia:
export NPM_TOKEN=tu_token # macOS / Linuxsetx NPM_TOKEN tu_token # Windows, solo shells nuevas
npm config ls -l imprime la configuración combinada completa, que es la forma más rápida de confirmar si el token se ha cogido.
Cómo arreglarlo en CI
El sitio donde más muerde esto es la integración continua, porque el runner es una máquina nueva sin ninguno de tus exports locales. La solución es entregar el secreto al paso como variable de entorno, con el mismo nombre NPM_TOKEN que espera el .npmrc. En GitHub Actions:
Si generas el .npmrc en el runner en vez de subirlo al repo, escribe la línea de autenticación directamente en el fichero de usuario antes de instalar:
echo "//npm.pkg.github.com/:_authToken=${NPM_TOKEN}" >> ~/.npmrcecho "@tu-scope:registry=https://npm.pkg.github.com/" >> ~/.npmrc
La idea es la misma en cualquier proveedor de CI: la referencia del .npmrc y la variable de entorno tienen que coincidir en el nombre, y el valor tiene que llegar al proceso que ejecuta la instalación.
Mantén el token fuera de git
Una última cosa, porque es un fallo que veo a menudo. El .npmrc que referencia ${NPM_TOKEN} se puede subir sin problema: solo contiene el nombre de la variable, no su valor. Lo que nunca debe llegar a git es un .npmrc con el token literal pegado (_authToken=ghp_...). Si lo hiciste, el token queda comprometido en el momento en que se sube — revócalo y rótalo en GitHub, no basta con borrar el fichero, porque el historial de git lo conserva. La regla: un .npmrc que solo referencia variables de entorno se puede subir y hasta ayuda a tus compañeros; uno con secretos reales va al .gitignore y, mejor aún, no debería existir.
Ya pase en local o en un pipeline, la pregunta es siempre la misma: ¿tiene la shell que ejecuta npm realmente
NPM_TOKEN, y está leyendo el.npmrcque crees? Responde a esas dos y el error desaparece.
