[Revisión completa] Un diagnóstico de fallos de Codex Desktop saboteado por pwsh.cmd: del desvío de WSL a la causa real en Windows Native (batch file arguments are invalid)

Esta depuración merece mucho la pena documentarla completa, porque prácticamente pisó casi todas las clases de “minas” más típicas al usar herramientas de IA de escritorio en Windows: API personalizada, WSL, Windows native, PowerShell, PATH, shim, binarios integrados de la versión de la tienda, y el clásico “parece que apareció de repente, pero en realidad es un problema antiguo que se reactivó”.

Para empezar por la conclusión:

Lo que realmente hizo que Codex Desktop no pudiera ejecutar comandos en absoluto bajo Windows native no fue WSL, ni el profile de PowerShell, ni la discrepancia de versiones entre la app de escritorio y la de npm, sino un shim en forma de batch escondido en C:\\Users\\1\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\pwsh.cmd. El ejecutor de comandos de Windows de Codex, al arrancar este envoltorio .cmd con parámetros, falla directamente con: batch file arguments are invalid, y por eso todos los comandos mueren antes de llegar a ejecutarse.

1. Punto de partida del incidente: parecía que “se rompió al cambiar a WSL”

Al principio, el síntoma superficial tenía en realidad dos capas:

  1. Tras cambiar tanto el Agent como el Integrated terminal en la configuración de Codex a WSL, el escritorio empezó a reconectar sin parar y a dar el error:
Reconnecting... 1/5
...
stream disconnected before completion: error sending request for url (https://wuju.de5.net/v1/responses)
  1. Pero el usuario dejó claro: no arreglemos WSL todavía; primero hay que resolver el problema original de Windows native, porque al principio ya fallaba en native, y por eso se cambió a WSL.

Este paso es importante, porque separa dos problemas:

  • La ruta WSL se parece más a un problema de red/proxy/acceso al endpoint personalizado desde el entorno WSL.
  • La ruta Windows native, en cambio, indica que el ejecutor local de comandos ya estaba roto.

Si no se separan, después se estará rebotando entre dos fallos independientes y se seguirá diagnosticando mal.

2. Primera reproducción mínima: no es que falle “un comando”, es que “todos mueren antes de ejecutarse”

Para confirmar si el problema era Git, PowerShell o Codex en sí, hicimos una prueba con comandos mínimos:

  • Write-Output hi
  • Get-Location
  • git status -sb
  • cmd.exe /c echo hi

El resultado fue perfectamente uniforme: todos fallaban con el mismo error:

execution error: Io(Error { kind: InvalidInput, message: "batch file arguments are invalid" })

Esto es muy valioso porque indica directamente:

  • No es un problema específico de Git.
  • No es un problema de un directorio de trabajo concreto.
  • No es que algún script del profile de PowerShell esté rompiendo un comando concreto.
  • Ni siquiera cmd.exe /c (una vía “para saltarse PowerShell”) se salva.

Es decir, el punto de fallo está en la “capa de arranque del comando”, no en el comando en sí.

3. Segundo punto engañoso: el terminal integrado funciona, ¿por qué Codex dice que no?

En ese momento, la captura del terminal integrado del hilo se veía normal: aparecía el prompt y se veía:

PowerShell 7.5.4
PS C:\Users\1\0.0.90_0>

Esto lleva fácilmente a pensar:

  • Si el terminal abre, PowerShell en sí debería estar bien.
  • Entonces lo más probable es un bug del runner interno de Codex.

Ese juicio era solo medio correcto.

PowerShell como tal no estaba roto, pero en Codex Desktop “que el terminal se muestre” no equivale a “que el ejecutor de comandos del agente pueda iniciar el shell con parámetros y ejecutar comandos”. Son dos rutas distintas.

Este fue el primer gran aprendizaje de esta depuración:

Que el terminal integrado interactivo funcione no prueba que la cadena shell_command del agente funcione.

4. Tercer error de interpretación: se llegó a sospechar que la versión de la tienda traía un backend antiguo

Luego encontramos algo muy sospechoso:

  • En los recursos de la versión de Microsoft Store, el CLI/runner bundled era 0.112.0-alpha.3
  • En la máquina, @openai/codex instalado globalmente vía npm ya era 0.113.0

Esto parecía muchísimo la causa raíz, porque “carcasa de escritorio nueva + runtime integrado viejo” sí puede generar comportamientos absurdos.

Así que hicimos una verificación bastante hardcore pero muy valiosa:

  • Copiar desde la versión de Store una copia editable de la app de escritorio.
  • Sustituir dentro los binarios instalados por npm de 0.113.0, reemplazando codex.exe, codex-command-runner.exe, etc.
  • Arrancar la versión parcheada y reproducir en un hilo nuevo.

Si de verdad era una discrepancia de versiones, la versión parcheada debería recuperarse.

El resultado fue: no se recuperó en absoluto.

En el hilo nuevo, el git status -sb más simple seguía fallando igual:

batch file arguments are invalid

Este paso fue crucial porque descartó de frente una hipótesis que parecía muy “de causa raíz”.

La conclusión pasó a ser:

  • La discrepancia entre 0.112.0-alpha.3 y 0.113.0, como mucho, es ruido o un problema aparte que merece atención.
  • Pero no es la causa raíz del colapso del shell native.

Este fue el segundo gran aprendizaje:

Hay muchos “puntos sospechosos” que pueden explicar el fenómeno, pero si un experimento de parche no elimina el síntoma, no es la causa raíz.

5. Seguir descartando: el profile de PowerShell hace ruido, pero no fue el punto mortal

A mitad del proceso también aparecieron errores del profile de PowerShell, por ejemplo: tras leer .wt_proxy_config.json como null, la lógica Add-Member/$cfg.enabled y similares explotaba dentro del profile.

Estos errores, por supuesto, hay que arreglarlos, porque ensucian el arranque del terminal y hacen sospechar de la inicialización del shell.

Pero aquí hay un juicio clave:

Si la causa real fuera el profile, al menos algunas rutas de comando deberían poder evitarlo, o la forma del error debería parecerse más a una excepción de script de PowerShell, no a que todos los comandos fallen uniformemente en la capa de arranque con batch file arguments are invalid.

Más tarde, los hechos confirmaron que el profile no era la causa principal de que el ejecutor native quedara totalmente inutilizado.

6. El verdadero punto de inflexión: se encontró un pwsh.cmd muy extraño

Al final, lo que clavó el problema fue descubrir en la máquina este archivo:

C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd

Su contenido tenía solo dos líneas:

@echo off
"C:\Program Files\PowerShell\7\pwsh.exe" %*

Esto parece un “shim bienintencionado” cuyo objetivo es envolver pwsh y reenviarlo al PowerShell 7 real.

Pero para el ejecutor de Windows de Codex Desktop, esto es veneno:

  • No es pwsh.exe, sino un envoltorio .cmd (batch).
  • En alguna ruta, el ejecutor de comandos de Codex lo invoca con parámetros y dispara directamente:
batch file arguments are invalid

Dicho de otra forma: antes de llegar a pwsh.exe, ya muere en la capa .cmd.

Esto también explica perfectamente por qué:

  • Write-Output hi muere
  • Get-Location muere
  • git status -sb muere
  • cmd.exe /c echo hi también muere

Porque lo que revienta es el bootstrap del shell más externo, no el comando objetivo.

7. Cadena de evidencias clave: este agujero no se generó hoy

La parte más interesante y contraintuitiva está aquí.

La percepción del usuario fue: “parece que apareció de repente hace unas tres horas; antes no había problemas”.

Pero los logs muestran que este problema es más antiguo que “hoy apareció de repente”:

Evidencia 1: el shim pwsh.cmd ya se escribió el 2026-02-02 18:52:53 (hora local)

En codex-tui.log se ve una acción clara de escritura: se escribió pwsh.cmd directamente dentro del directorio Scripts de Python.

Evidencia 2: el mismo tipo de error aparece ya desde el 2026-02-03 15:02:40 (hora local)

En los logs, desde el 3 de febrero ya aparecen muchas entradas como:

exec error: batch file arguments are invalid

Incluso hay registros explícitos de intentos de invocar ese shim.

Evidencia 3: la falla actual se reexpuso alrededor del 2026-03-11 04:11, y el experimento de reproducción de las 04:33 la golpeó de forma estable

Es decir: hoy no es “que esta configuración mala se creara hoy”, sino “que este riesgo antiguo se volvió a disparar hoy y justo cayó en la ruta de uso actual”.

8. Entonces, ¿por qué el usuario siente que “se rompió de repente hace tres horas”?

Este es el punto que más merece explicarse.

La formulación más precisa sería:

No es que hace tres horas se generara la mala configuración, sino que hace tres horas Codex Desktop volvió a pasar por la ruta de ejecución que impacta pwsh.cmd.

Con la evidencia disponible, creo que la explicación más razonable es esta combinación, y no “el software se actualizó en secreto”:

  1. La mina pwsh.cmd llevaba tiempo enterrada.
  2. A principios de febrero ya causó errores del mismo tipo, pero no siempre se manifiesta de la misma manera en cada uso.
  3. Esta vez, al depurar, el usuario volvió a Windows native + rutas relacionadas con PowerShell.
  4. A la vez, el escritorio/backend volvió a cargar un entorno persistente y resolvió pwsh otra vez vía PATH.
  5. Esta resolución acertó contra el shim .cmd, y el problema explotó de nuevo de forma total.

En otras palabras, este tipo de fallo puede “aparecer de repente” sin necesidad de que haya actualización.

Con que ocurra cualquiera de estas cosas, se puede reactivar un riesgo viejo:

  • Reinicio de la app de escritorio
  • Reinicio del proceso agent en segundo plano
  • Cambiar de WSL a Windows native
  • Re-inicializar el shell tras cambiar ajustes
  • Que algún hilo nuevo deje de reutilizar el entorno antiguo y vuelva a leer el PATH persistente

Aquí hay que ser honesto:

Puedo confirmar la estructura “riesgo antiguo + nuevo disparador”, pero con los logs actuales no puedo demostrar al 100% qué acción exacta fue el momento de disparo.

Pero sí se puede afirmar con mucha certeza: no es “una nueva configuración mala desconocida creada hoy de repente”.

9. Acción final de reparación

La acción que devolvió Windows native a la normalidad fue simple, pero tenía que ser precisa:

Acción 1: mover ese shim fuera del camino

Renombrar:

C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd

a:

C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd.disabled-by-codex

Acción 2: poner PowerShell 7 antes en el PATH del usuario

Poner explícitamente:

C:\Program Files\PowerShell\7\

al principio del Path del usuario, para evitar que futuras resoluciones vuelvan a chocar primero con otros shims.

Acción 3: difundir el cambio de variables de entorno

No solo se cambió el registro: también se envió explícitamente WM_SETTINGCHANGE / Environment para que los procesos nuevos obtengan cuanto antes el entorno actualizado.

Acción 4: el script de arranque parcheado también hace prepend de PowerShell 7

Así, incluso si en el futuro otro lugar vuelve a modificar PATH, esta cadena de arranque es menos fácil de contaminar.

Tras la reparación, el usuario ya confirmó: por fin volvió a funcionar.

10. ¿En qué desvíos se cayó esta vez? ¿Por qué siguen valiendo la pena?

Parece que se dio muchas vueltas, pero cada desvío fue reduciendo el espacio de búsqueda:

Desvío 1: primero se dejó engañar por el error de red en WSL

Valor: confirmar que el problema de WSL y el de native no eran el mismo fallo.

Desvío 2: sospechar del profile de PowerShell

Valor: separar el “ruido de inicialización del terminal” del “fallo fatal del ejecutor de comandos”.

Desvío 3: sospechar de que el backend bundled del escritorio iba atrasado

Valor: con el experimento de app parcheada, descartar directamente que sea “solo un problema de versión”.

Desvío 4: probar distintas entradas de comando

Por ejemplo, ejecutar directamente:

  • Write-Output hi
  • cmd.exe /c echo hi
  • powershell -NoProfile -Command ...
  • & git.exe status -sb

Valor: demostrar que todas las rutas fallan de forma previa en la misma capa, y no por un bug específico de un shell.

Así que estos “desvíos” no fueron en vano: fueron comprimiendo el problema desde “podría ser cualquier parte” hasta “solo puede ser un problema muy de bajo nivel de bootstrap del shell de Windows / PATH / shim”.

11. Los aprendizajes más prácticos

Experiencia 1: en herramientas de IA de escritorio, “el terminal se ve bien” no significa que el ejecutor del agente esté bien

El terminal UI y la cadena de ejecución de comandos en segundo plano son dos cosas distintas.

Experiencia 2: las pruebas de comandos más cortas valen oro

Pruebas como Write-Output hi, Get-Location, cmd.exe /c echo hi son mucho más efectivas que empezar con comandos complejos.

Experiencia 3: diferencia de versión no equivale a causa raíz

Si sustituyes el binario por otra versión y el fenómeno no cambia nada, el problema de versión, como mucho, es un fenómeno acompañante.

Experiencia 4: los shims en Windows son muy traicioneros

En especial .cmd, .bat, el directorio Scripts de Python, los stubs proxy de WindowsApps, etc. Normalmente parecen inofensivos, pero en cuanto un programa resuelve comandos de una forma distinta a la que imaginas, explota de manera muy absurda.

Experiencia 5: que el usuario “sienta que hoy se rompió de repente” no implica que “la causa raíz apareció hoy”

Muchos problemas a nivel sistema tienen esta estructura real:

  • El riesgo existe desde hace mucho
  • Durante mucho tiempo no se impacta
  • Tras un reinicio de proceso/cambio de modo/recarga de entorno, de pronto estalla por completo

Experiencia 6: la línea temporal de los logs es extremadamente importante

Si solo miras el estado actual, es fácil confundir “se disparó hoy” con “se creó hoy”.

12. La conclusión más esencial en una frase

Esto no fue un simple “Codex se rompió”, sino un caso típico de contaminación del entorno en Windows: un shim pwsh.cmd enterrado desde hace tiempo volvió a ser resuelto en una ruta de shell Windows native, y terminó volando por los aires todo el ejecutor de comandos de Codex Desktop.

Si en el futuro te encuentras algo parecido:

  • todos los comandos fallan de forma uniforme
  • el error es corto y no tiene relación con el contenido del comando
  • el terminal integrado abre pero el agente no puede ejecutar
  • distintas entradas de comando dan exactamente el mismo error

Entonces deja de mirar Git, el repositorio, el profile, e incluso la versión de la app: prioriza revisar:

  • where.exe pwsh
  • el orden de PATH
  • si existe algún shim .cmd/.bat con el mismo nombre
  • si en WindowsApps / Python Scripts / directorios de launchers personalizados hay envoltorios escondidos

En este tipo de problemas, una vez encontrada la causa raíz, la reparación suele ser pequeña.
Lo verdaderamente difícil es: entre un montón de ruido que parece causa raíz, encontrar a la fuerza la mina real.

TL;DR: Esta vez no fue WSL, ni el repositorio local, ni el profile de PowerShell, ni una discrepancia de versiones de la app de escritorio lo que rompió Codex; la verdadera causa raíz fue que pwsh en el PATH resolvía primero a un wrapper .cmd, en lugar del binario real pwsh.exe.

En concreto, en esta máquina había:

C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd

Cuando el ejecutor de comandos de Windows de Codex llamaba a este shim con parámetros, fallaba directamente con:

batch file arguments are invalid

Así que en apariencia era “todos los comandos están rotos”, pero en esencia el bootstrap del shell más externo explotaba antes de que el comando se ejecutara de verdad.

La corrección también es bastante directa:

  • Mover/renombrar este pwsh.cmd
  • Poner C:\Program Files\PowerShell\7\ antes en el PATH
  • Reiniciar Codex para que el nuevo entorno surta efecto

Otra experiencia clave: que el usuario sienta que “se rompió de repente hoy” no significa que la causa raíz haya aparecido hoy. En los logs se ve que este shim y errores similares en realidad ya existían antes; esta vez solo se volvió a resolver hacia él tras algún reinicio/cambio de ruta.