Problemas comunes de npm y cómo solucionarlos de forma segura

Actualización definitiva: 03/16/2026
  • La mayoría de los problemas de npm se deben a problemas de configuración del entorno, como las políticas de ejecución y los permisos, más que al propio npm.
  • Instalaciones deterministas con npm ci y uso cuidadoso de npm audit reducir los riesgos de vulnerabilidad y de la cadena de suministro.
  • Evitar sudo npmAl reducir las dependencias innecesarias y utilizar prefijos a nivel de usuario, las instalaciones globales son más seguras y estables.
  • El registro detallado, el comando npm doctor y las reinstalaciones limpias ocasionales son herramientas esenciales para diagnosticar y resolver errores persistentes de npm.

Problemas de solución de problemas de npm

Encontrarse con problemas extraños de npm puede ser increíblemente frustrante, especialmente cuando lo único que querías era instalar un paquete y volver a programar. Desde scripts que bloquean PowerShell en Windows, hasta pesadillas con los permisos en Linux, pasando por interminables listas de vulnerabilidades en el informe de auditoría, los errores de npm pueden convertirse rápidamente en horas de productividad perdida si no sabes lo que estás viendo.

Esta guía te explica los problemas más comunes que surgen al usar npm en el mundo real, te explica por qué ocurren y te ofrece soluciones prácticas y probadas. Analizaremos las políticas de ejecución de Windows, los errores de permisos globales, las trampas de seguridad en el ecosistema npm, la diferencia entre las vulnerabilidades de desarrollo y producción, qué npm ci Realmente funciona, y también explica cómo depurar instalaciones defectuosas y problemas de caché sin entrar en pánico.

La política de ejecución de PowerShell bloquea npm en Windows.

Uno de los primeros obstáculos con los que se encuentran muchos usuarios de Windows tras instalar Node.js es que npm simplemente se niega a ejecutarse en PowerShell. La terminal muestra un error similar a "no se puede cargar el archivo". C:\Program Files\nodejs\npm.ps1 porque la ejecución de scripts está deshabilitada en este sistema”, junto con un PSSecurityException y una sugerencia para leer about_Execution_Policies.

Este problema no tiene nada que ver con una mala instalación de Node.js; se trata de una función de seguridad de PowerShell llamada política de ejecución. Por defecto, algunas configuraciones de Windows impiden que se ejecute cualquier script local (incluido el propio envoltorio de PowerShell de npm), lo que hace que PowerShell trate npm.ps1 como contenido potencialmente inseguro.

Para solucionar esto, normalmente es necesario flexibilizar la política de ejecución de PowerShell para el usuario actual, en lugar de deshabilitar la seguridad por completo a nivel del sistema. Un enfoque común es ejecutar PowerShell como administrador y usar un comando como Set-ExecutionPolicy RemoteSigned -Scope CurrentUser, lo que permite la creación de scripts localmente, pero sigue bloqueando los scripts remotos no firmados.

Si prefiere no modificar la política de PowerShell en absoluto, puede solucionar esto utilizando el Símbolo del sistema (cmd.exe) o la Terminal de Windows con un intérprete de comandos diferente. En esos entornos, npm no pasa por un script de PowerShell, por lo que la restricción no se aplica y su npm Los comandos deberían ejecutarse siempre que Node.js esté correctamente añadido a su PATH.

Qué hace realmente npm ci y por qué es importante.

Una vez que npm está en ejecución, otro comando que suele generar preguntas es: npm ci, que se comporta de manera diferente a la más familiar npm install. Si bien ambos instalan dependencias, npm ci Está diseñado específicamente para entornos limpios y reproducibles, como las canalizaciones de integración continua (CI).

La diferencia clave es que npm ci ignora los rangos de versiones en package.json e instala exactamente las versiones fijadas en package-lock.json. Esto significa que ninguna versión de dependencia "compatible pero más reciente" se cuele en tu compilación solo porque se publicaron más tarde; cada instalación es determinista siempre que el archivo de bloqueo permanezca igual.

Desde una perspectiva de rendimiento, npm ci Suele ser más rápido para la integración continua porque omite ciertos pasos de resolución de dependencias y parte de cero. Espera que tu node_modules El directorio está vacío o se borrará, lo que permite a npm evitar muchas comprobaciones y actualizaciones adicionales que npm install normalmente funcionaría.

Desde el punto de vista de la seguridad y la cadena de suministro, npm ci Reduce drásticamente el riesgo de que se cuelen cambios de dependencia no revisados ​​en las versiones de producción. Dado que nunca busca versiones compatibles más recientes, en la práctica se congela el árbol de dependencias a lo que el equipo ha bloqueado y auditado, lo que facilita enormemente la reproducción de incidentes y el análisis de vulnerabilidades.

Los equipos centrados en la seguridad a menudo combinan npm ci con herramientas de escaneo de dependencias automatizadas que inspeccionan cada paquete, incluidos aquellos bloqueados en el package-lock.json . De esta forma, incluso si el archivo de bloqueo estaba limpio cuando se realizó la confirmación, las vulnerabilidades recién descubiertas o los paquetes maliciosos aún pueden detectarse durante la compilación de CI antes de que se implemente la aplicación.

Permisos globales de npm y la regla "nunca usar sudo npm"

En los sistemas tipo Unix (Linux, macOS), una de las categorías más conocidas de problemas con npm proviene de la instalación de paquetes globales con privilegios elevados. Si alguna vez ha visto advertencias como "Falta acceso de escritura a /usr/lib/node_modules” o errores como EACCES: permission deniedTe has topado con este tipo de problema.

Por defecto, npm a menudo intenta colocar los paquetes instalados globalmente en /usr (por ejemplo /usr/lib/node_modules y ejecutables en /usr/bin), que son directorios del sistema que normalmente pertenecen al usuario root. Cuando los usuarios comienzan a ejecutar sudo npm install -g ... Para “corregir” los errores de permisos, los archivos y directorios pasan a ser propiedad del usuario root, lo que provoca que los comandos ejecutados posteriormente como un usuario normal presenten problemas de acceso de escritura.

La conclusión principal es simple: no ejecute npm como root y evite usar sudo No uses npm a menos que estés completamente seguro de lo que estás haciendo. Además del caos que suponen los permisos, instalar JavaScript de terceros como administrador también aumenta el impacto de cualquier paquete malicioso o comprometido, otorgándole control total sobre el sistema.

Para comprobar dónde está colocando actualmente npm los paquetes globales, puede ejecutar npm config get prefix, que normalmente devolverá algo como /usr en una configuración problemática. Ese prefijo determina dónde se ubican los módulos globales y sus binarios, por lo que si el prefijo apunta a una ruta del sistema, los problemas de permisos son prácticamente inevitables a largo plazo.

Una solución segura y recomendada es mover el prefijo global de npm al directorio personal del usuario, donde se tiene control total sin necesidad de privilegios elevados. Un patrón típico es crear un directorio como por ejemplo: ~/.npm-global Y luego ejecutar npm config set prefix '~/.npm-global' para que todas las futuras instalaciones globales aterricen allí en lugar de en /usr.

Tras cambiar el prefijo, debe añadir el nuevo directorio de binarios globales a su variable PATH para que el sistema pueda encontrar los comandos instalados globalmente. Por ejemplo, podrías agregar una línea como export PATH=~/.npm-global/bin:$PATH a su archivo de inicio de shell (como ~/.bashrc or ~/.zshrc), luego reinicie la terminal para que el cambio surta efecto.

Una vez que esto esté configurado correctamente, vuelva a ejecutarlo. npm doctor se convierte en una buena comprobación de cordura: debería informar que los archivos en caché y globales node_modules son legibles y modificables por su usuario actual. Tenga en cuenta que al cambiar a un directorio global nuevo, los paquetes globales instalados previamente ya no estarán presentes y deberá reinstalar los que realmente utiliza.

Uso de npm doctor para diagnosticar problemas del entorno

Muchos problemas con npm no se deben a un proyecto específico, sino a un entorno npm defectuoso o inconsistente en tu máquina. El comando npm doctor Está diseñado precisamente para esto: ejecuta una serie de comprobaciones de estado en tu configuración de npm y resalta los posibles problemas.

Cuando ejecutas npm doctornpm comprueba la conectividad con el registro, verifica las versiones de npm y Node.js, revisa la URL del registro configurada e inspecciona los permisos en las carpetas de caché y los directorios de módulos globales. Cada comprobación se informa con un estado de "correcto" o "incorrecto", lo que facilita la detección de errores de configuración.

Por ejemplo, si npm encuentra que directorios como /usr/lib/node_modules or /root/.npm Si su usuario normal no puede modificar estos elementos, verá los relacionados con permisos marcados como "notOk" en rojo. Eso es un fuerte indicio de que npm se ejecutó previamente como root o a través de sudo, dejando tras de sí archivos propiedad del usuario root que bloquean las operaciones normales.

El comando doctor también puede revelar herramientas faltantes que npm espera, como Git, que es necesario para algunas dependencias que usan URL de Git en lugar de paquetes de registro publicados. Si Git no está instalado o no se encuentra en su variable de entorno PATH, verá una advertencia que le instará a instalarlo e intentarlo de nuevo.

Después de solucionar cualquier problema npm doctor Según los informes, al ejecutarlo de nuevo debería mostrar todos los estados verdes "ok", lo que indica una instalación de npm correcta. Utilice este comando como una comprobación básica del estado del sistema siempre que sospeche que la configuración de npm a nivel global podría ser la causa de errores extraños que observe durante las instalaciones o auditorías.

Qué frágil puede ser el ecosistema de npm: incidentes y riesgos famosos

Más allá de los problemas de configuración local, es importante comprender que npm, como ecosistema, tiene sus propios riesgos estructurales, derivados de enormes árboles de dependencias y de un sistema de mantenimiento mayoritariamente voluntario. Los proyectos modernos de JavaScript suelen incorporar cientos o incluso miles de paquetes, muchos de los cuales son mantenidos por tan solo una o dos personas en su tiempo libre.

Esta fragmentación extrema hace que sea casi imposible revisar manualmente todo lo que termina en su solicitud final, lo que abre la puerta a ataques a la cadena de suministro en npm y vulnerabilidades sutiles. Un único paquete comprometido o abandonado puede propagarse en cascada a través del gráfico de dependencias y afectar a un gran número de proyectos sin que los desarrolladores se den cuenta de inmediato.

Un ejemplo clásico de esta fragilidad es el incidente de 2016 que involucró un pequeño paquete llamado left-pad, que constaba de aproximadamente 11 líneas de código. Su único propósito era rellenar las cadenas de caracteres por la izquierda hasta que alcanzaran una longitud determinada, pero fue utilizado, directa e indirectamente, por innumerables paquetes y herramientas importantes como el compilador JavaScript Babel.

Tras una disputa entre el autor y npm, el mantenedor decidió retirar de la publicación varios de sus paquetes, entre ellos: left-pad, del registro. Debido a que npm no conservaba instantáneas inmutables de las versiones publicadas en ese momento, la eliminación provocó fallos inmediatos en las compilaciones de todo el mundo que dependían de esas versiones exactas, dejando a los desarrolladores con instalaciones defectuosas.

En una medida sin precedentes, npm Inc. restauró la última versión conocida de left-pad ellos mismos, sin el consentimiento del autor, para reactivar el ecosistema. Esa decisión fue controvertida porque contradecía la idea de que los autores controlan el ciclo de vida de sus paquetes, pero también puso de manifiesto hasta qué punto la infraestructura crítica dependía de módulos triviales de terceros.

Más allá de los incidentes de disponibilidad, ha habido numerosos casos centrados en la seguridad en los que paquetes populares de npm se vieron comprometidos o se descubrió que contenían vulnerabilidades graves. Esto incluye situaciones en las que los responsables del mantenimiento fueron víctimas de ingeniería social, se usurpó la propiedad de paquetes abandonados o se explotaron fallos sutiles para ejecutar código arbitrario.

Un ejemplo ampliamente comentado es el de 2018. event-stream Se produjo un ataque informático en el que un atacante obtuvo el control de una popular aplicación de streaming e inyectó código destinado a robar criptomonedas de las aplicaciones afectadas. Gracias event-stream Al ser una dependencia en muchos otros paquetes, el código malicioso se propagó silenciosamente a través de las cadenas de dependencias hasta los sistemas de producción.

Otro caso es la vulnerabilidad de inyección de comandos de 2019 en coa, una herramienta de ayuda de línea de comandos utilizada por varias herramientas muy conocidas. En determinadas condiciones, una entrada de usuario que no haya sido debidamente sanitizada podría transformarse en comandos de shell arbitrarios, lo que abriría la puerta a la ejecución remota si la vulnerabilidad se activara en un contexto vulnerable.

Bibliotecas de alto perfil como axios También han presentado vulnerabilidades, como problemas de falsificación de solicitudes del lado del servidor (SSRF, por sus siglas en inglés) que permiten a los atacantes redirigir los servidores para realizar solicitudes a recursos internos. Incluso utilidades ultracomunes como minimist Se vieron afectados por fallos de contaminación de prototipos, lo que permitió a los atacantes manipular los prototipos de objetos y alterar potencialmente el comportamiento de las aplicaciones de maneras sutiles y peligrosas.

La principal lección es que incluso los paquetes muy populares o aparentemente inofensivos no son automáticamente seguros; pueden ser explotados, abandonados o mal configurados como cualquier otro software. Por eso, una postura de seguridad sólida en torno a npm requiere tanto herramientas técnicas (auditorías, escaneo, bloqueo) como hábitos culturales (actualizaciones periódicas, selección cuidadosa de dependencias y preferencia por escribir utilidades sencillas internamente cuando sea factible).

Vulnerabilidades en entornos de desarrollo frente a entornos de producción

Cuando los desarrolladores ejecutan por primera vez npm audit En un proyecto, la larga lista de vulnerabilidades puede parecer aterradora, pero no todas afectan realmente a la aplicación en producción que está en funcionamiento. Muchos de los problemas detectados residen en herramientas que se utilizan únicamente durante el desarrollo o la fase de compilación.

La distinción clave radica en las dependencias declaradas en dependencies y aquellos bajo devDependencies in package.json. Paquetes en devDependencies Por lo general, solo son necesarios para tareas como la agrupación, la transpilación, el análisis estático de código o la ejecución de servidores de prueba, y no están pensados ​​para ser incluidos como parte del paquete de producción final o del entorno de ejecución del servidor.

Por ejemplo, vulnerabilidades en herramientas como webpack-dev-server, @angular-devkit o vite Por lo general, esto importa mientras se desarrolla localmente, no una vez que se ha implementado la versión de producción. Estos servidores de desarrollo y herramientas de compilación pueden exponer vulnerabilidades como la fuga de código de origen cruzado o comportamientos similares a SSRF, pero solo mientras el servidor de desarrollo esté en funcionamiento y accesible.

Corriendo una llanura npm audit El informe normalmente incluirá vulnerabilidades tanto de tiempo de ejecución como de solo desarrollo, mostrando problemas en paquetes como brace-expansion, esbuildy el ámbito webpack-dev-server. La auditoría a menudo sugerirá npm audit fix o incluso npm audit fix --force para aumentar las versiones, lo que a veces requiere actualizaciones importantes en marcos de trabajo como Angular para eliminar las advertencias.

Para ver qué vulnerabilidades realmente afectan a lo que se implementa en producción, puede ejecutar npm audit --production (o utilice el recomendado) --omit=dev opción en versiones más recientes de npm). Si este comando devuelve "no se encontraron vulnerabilidades", significa que, según la base de datos de avisos de npm, su conjunto de dependencias de producción está actualmente libre de problemas conocidos.

Esto no significa que puedas ignorar para siempre las vulnerabilidades exclusivas para desarrolladores, ya que aún pueden poner en riesgo las máquinas o el código fuente de los desarrolladores mientras trabajan en el proyecto. Sin embargo, comprender la diferencia permite establecer prioridades: solucionar primero los problemas de producción de alto impacto y, a continuación, abordar los problemas del entorno de desarrollo de forma planificada, en lugar de reaccionar ante cada advertencia como si fuera igualmente crítica.

Cómo funciona npm audit fix y cuándo evitar –force

El comando npm audit fix Está diseñado para actualizar automáticamente las dependencias vulnerables dentro de rangos de versiones seguras, pero no es un botón mágico que lo resuelva todo sin contrapartidas. Recorre tu árbol de dependencias buscando paquetes con problemas conocidos e intenta actualizarlos a versiones parcheadas que sigan siendo compatibles con tus dependencias existentes. package.json restricciones

Por ejemplo, si se especifica una dependencia como ^1.2.0, npm intentará pasar a la última versión 1.x versión que contiene la corrección, sin saltar directamente a 2.x, lo que podría introducir cambios incompatibles. Esto hace npm audit fix Es relativamente seguro para muchos proyectos, ya que respeta las restricciones de versionado semántico.

Sin embargo, a veces los únicos parches disponibles están en versiones principales más recientes o en cadenas de herramientas que requieren actualizaciones más amplias, que es cuando npm sugiere usar npm audit fix --force. Esta bandera le indica a npm que tiene permiso para instalar actualizaciones que podrían causar problemas, incluidos los aumentos de versión principales y los cambios en cascada en los marcos de trabajo o las herramientas de compilación.

Corriendo a ciegas --force En un proyecto grande o heredado, esto puede fácilmente provocar fallos en la compilación o regresiones sutiles en tiempo de ejecución, ya que las dependencias de las que depende su código pueden cambiar su comportamiento o sus API. Piénsalo como si optaras por una minimigración de tu infraestructura, no solo por un parche de seguridad, por lo que debe hacerse con pruebas y medidas de seguridad de control de versiones implementadas.

También hay casos en los que npm simplemente no puede solucionar automáticamente todas las vulnerabilidades, normalmente porque las actualizaciones de versión necesarias entrarían en conflicto con otras restricciones en el gráfico de dependencias. En esas situaciones, es posible que deba actualizar o reemplazar manualmente ciertas bibliotecas, o aceptar un nivel de riesgo temporal hasta que se publique un parche que no genere cambios indeseables.

Una estrategia práctica consiste en comprender primero qué vulnerabilidades afectan a la producción y luego aplicar npm audit fix sin --forcey solo se deben considerar las actualizaciones forzadas o importantes después de un análisis de impacto y con una cobertura de pruebas adecuada. De esta forma, mantienes tu aplicación segura sin desestabilizar constantemente tu código fuente en aras de obtener un informe de auditoría impecable.

En definitiva, abordar las vulnerabilidades de npm es un proceso continuo de evaluación de riesgos, priorización y actualizaciones controladas, no un comando que se ejecuta una sola vez y se olvida. Cada problema debe evaluarse en función de su gravedad, su posible explotación en el mundo real dentro de su contexto y el coste de actualizar los paquetes o conjuntos de herramientas afectados.

Repensar cuántas dependencias de npm realmente necesitas

Una de las prácticas de seguridad a largo plazo más efectivas con npm consiste simplemente en depender de la menor cantidad posible de paquetes de terceros, siempre que sea razonablemente posible. Cada dependencia adicional aumenta la superficie de ataque, la carga de mantenimiento y el potencial de problemas transitorios inesperados en el futuro.

Los desarrolladores suelen instalar paquetes por comodidad, incluso cuando la funcionalidad podría implementarse en unas pocas líneas de JavaScript puro. Con el tiempo, este hábito puede sobrecargar tu árbol de dependencias con módulos que apenas se usan, que reciben un mantenimiento deficiente o que se pueden reemplazar fácilmente con pequeños fragmentos de código propio.

Reducir las dependencias tiene múltiples beneficios más allá de la seguridad: proyectos más pequeños, tiempos de instalación y compilación más rápidos, menos conflictos de versiones y una depuración más sencilla cuando algo falla. Un gráfico de dependencias más sencillo también facilita la auditoría de lo que realmente se incluye en tu aplicación, en lugar de tener que revisar páginas y páginas de paquetes transitorios que nunca elegiste conscientemente.

Desde la perspectiva del riesgo, un menor número de componentes implica menos posibilidades de que proyectos abandonados, responsables de mantenimiento comprometidos o vulnerabilidades sutiles en utilidades poco conocidas afecten a su infraestructura. Aunque no puedas evitar los grandes frameworks o las bibliotecas principales, aún puedes ser selectivo con las pequeñas herramientas auxiliares que realizan tareas triviales, las cuales a menudo representan una parte sorprendente del ruido de auditoría.

Una estrategia de dependencias madura implica evaluar críticamente los nuevos paquetes, eliminar periódicamente los que no se utilizan y, siempre que sea posible, priorizar las bibliotecas bien mantenidas y ampliamente probadas sobre las soluciones específicas o puntuales. Combinado con un buen uso de npm audit, npm ciCon actualizaciones periódicas, esta mentalidad puede reducir drásticamente la frecuencia y la gravedad de los problemas relacionados con npm a los que te enfrentas.

Depuración de errores, registros e instalaciones corruptas de npm

Incluso con un entorno bien configurado y un árbol de dependencias sencillo, tarde o temprano te encontrarás con errores de npm confusos que paralizarán tu flujo de trabajo. Una depuración eficaz comienza por obtener más información sobre lo que npm está haciendo realmente internamente cuando falla un comando.

Una técnica sencilla consiste en aumentar la verbosidad de npm utilizando indicadores como --dd (o --loglevel verbose), que imprime los pasos detallados del proceso. Este nivel de registro puede revelar exactamente qué operación falló, qué archivo o directorio causó el problema o qué script en su cadena de dependencias está fallando.

Cuando un comando falla, npm también suele indicar dónde almacenó un archivo de registro más detallado, normalmente en un directorio como ~/.npm/_logs. Al abrir ese registro, obtendrá un seguimiento cronológico de la instalación o la ejecución del script, incluidos los seguimientos de pila, los detalles del entorno y los errores subyacentes del sistema que no siempre aparecen en la breve salida de error.

Algunos fracasos provienen de errores propios. package.json, tales como JSON no válido, nombres de scripts incorrectos o rangos de versiones mal formados. En esos casos, revisar cuidadosamente el archivo en busca de errores de sintaxis, erratas o comas al final puede resolver problemas que, a primera vista, parecen misteriosos.

En otras ocasiones, la causa principal se encuentra en el sistema operativo o en la herramienta: problemas con el acceso a la red, la resolución de DNS, las reglas del firewall o credenciales de Git o GitHub mal configuradas. Por ejemplo, si una dependencia se obtiene directamente de un repositorio Git y Git no está instalado o está mal configurado, npm fallará aunque el registro sea accesible.

Los problemas de instalación de dependencias también pueden deberse a un archivo corrupto. node_modules caché de directorio o npm, especialmente después de instalaciones interrumpidas o actualizaciones incompletas. Si sospechas de corrupción, a menudo es más fácil eliminarla. node_modules y el archivo de bloqueo, borre la caché de npm y reinstale, en lugar de intentar arreglar paquetes individuales dañados in situ.

Un patrón de recuperación común es eliminar node_modules, opcionalmente ejecute un comando de limpieza de caché y luego ejecute npm install Nuevamente, hay que reconstruir el árbol de dependencias desde cero. Este reinicio drástico suele solucionar comportamientos extraños o inconsistentes que la resolución de problemas habitual no detecta, especialmente después de cambiar de rama o fusionar grandes cambios de dependencia.

Recuerda que no todos los errores son causados ​​directamente por npm; algunos se originan en los scripts que ejecutan los paquetes durante la instalación o en los ganchos del ciclo de vida de tu propio proyecto. Los registros detallados y los rastreos de pila de errores pueden ayudarte a determinar si se trata de un problema exclusivo de npm o de un problema en un script de terceros o una herramienta personalizada que se activa a través de npm.

En general, combinar un mejor registro, una lectura cuidadosa de los mensajes de error y el reinicio ocasional de node_modules Te ayudará a recuperarte de la mayoría de los fallos de npm sin quedarte atascado en ciclos interminables de prueba y error. Con el tiempo, reconocerás patrones recurrentes (errores tipográficos en JSON, problemas de permisos, herramientas faltantes) que harán que la siguiente sesión de depuración sea mucho más rápida.

Gestionar npm con éxito consiste, en última instancia, en comprender tanto las peculiaridades de las herramientas locales como los riesgos del ecosistema en general: desde las políticas de ejecución de PowerShell y los permisos de Unix, pasando por las instalaciones deterministas y las auditorías de vulnerabilidades, hasta la selección cuidadosa de dependencias y la depuración sistemática, cada buena práctica que adopte reduce las posibilidades de que los problemas de npm descarrilen su trabajo de desarrollo.

ataque Shai-Hulud a la cadena de suministro de npm
Artículo relacionado:
Shai-Hulud: el ataque que sacude la cadena de suministro de npm
Artículos Relacionados: