Configuraste un proveedor custom, codex funciona bien desde la terminal, pero el selector de modelos de Desktop actúa como si tus modelos no existieran.
Ese hueco casi nunca es tu API key ni la sintaxis de tu config. Es el cliente de Desktop filtrando silenciosamente modelos que el backend ya cargó. Las peticiones funcionan. El desplegable simplemente se niega a mostrarlos.
Esta guía hace dos cosas. Primera: las correcciones concretas, ordenadas desde un arreglo de una línea hasta un selector limpio y conmutable. Segunda — la parte que la mayoría de guías omite — lo que un bug de UI en una herramienta de la que dependes enseña de verdad sobre cómo está cableado tu stack de IA.
Si prefieres que alguien consolide toda la capa por ti, también hacemos eso.
DIAGNÓSTICO EN 30 SEGUNDOS
Empareja tu síntoma antes de editar nada
La mayoría de la gente está a una línea de config de un arreglo. Empareja lo que ves con la tabla y actúa.
| Lo que ves | Lo que está mal de verdad | Primer movimiento |
|---|---|---|
| El selector muestra solo "Custom", sin nombre de modelo | Modelo puesto inline, sin metadatos de catálogo | Fix 1: deja el modelo inline — funciona |
| codex CLI /model lo lista, Desktop no | Filtro del lado del cliente de Desktop (issue #19694) | Fix 1 ahora, Fix 4 para un listado real |
| El desplegable del selector está vacío | Catálogo ausente o mal formado | Fix 2 o Fix 4 |
| No carga nada, en el arranque imprime un warning | Proveedor en .codex/config.toml del proyecto | Fix 3: muévelo a ~/.codex/ |
| Proveedor nativo de cc-switch, sigue oculto | Formato de catálogo previo a v3.16.5 | Fix 4: actualiza y vuelve a guardar |
La comprobación más rápida: abre una terminal en la misma carpeta, ejecuta codex (el CLI) y escribe /model. Si el CLI lista tu modelo pero Desktop no, tienes el bug de filtrado del lado del cliente — y editar la config del lado de Desktop no lo va a hacer aparecer. Salta a Fix 1.
PRIMERA DECISIÓN
¿Arreglar la pantalla o arreglar la ruta?
Esta es la decisión que te ahorra una tarde editando la capa equivocada.
Arregla el selector (Fix 1–4) cuando
- Tus peticiones funcionan desde el CLI o con un curl directo, y el modelo simplemente no aparece en el desplegable de Desktop.
- Estás ante el filtro del lado del cliente #19694 o un hueco de catálogo — problemas de pantalla, no de enrutamiento.
- Quieres una lista de modelos limpia y conmutable para un equipo que cambia de modelo a menudo.
Arregla la ruta (no el selector) cuando
- Un curl a tu gateway devuelve 401, 404 o model-not-found. El proveedor o el string del modelo están mal.
- Cada petición 404 porque wire_api está puesto en el path chat ya retirado o el gateway no tiene endpoint /responses.
- El modelo funciona pero devuelve salida incorrecta — tu slug de catálogo no coincide con el ID del proveedor.
Regla de parada. Si tu único objetivo es enviar peticiones a un modelo custom, Fix 1 por sí solo te lleva ahí: pon el modelo inline, reinicia, listo. El resto trata de que el selector muestre una lista limpia y conmutable. Si nunca abres el desplegable, para tras Fix 1.
CAUSAS DE FONDO
Cuatro razones por las que el selector oculta tu modelo
Necesitan arreglos distintos. Elegir la equivocada es por qué la gente pasa una tarde reescribiendo una config que ya funcionaba.
| Causa de fondo | Por qué el selector oculta el modelo | Qué configuraciones la sufren | Fix |
|---|---|---|---|
| Filtro del lado del cliente de Desktop | El app-server devuelve el modelo vía model/list; el renderer de Desktop lo descarta. | Cualquier proveedor custom con catálogo | Fix 1 + Fix 4 |
| Sin metadatos de catálogo | model puesto inline, el selector no tiene nada que describir. | Configs mínimas de config.toml | Fix 1 o Fix 2 |
| Catálogo mal formado o caduco | Catálogo escrito en un formato que Codex no enumera. | cc-switch antiguo, JSON editado a mano | Fix 2 / Fix 4 |
| Proveedor a nivel de proyecto | model_provider se ignora fuera de ~/.codex/config.toml. | .codex/config.toml dentro de un repo | Fix 3 |
La primera sorprende. Según el issue abierto de codex #19694, el app-server carga el catálogo correctamente y devuelve tus modelos a través de su endpoint model/list — pero la UI de Desktop aplica un filtro extra y descarta los modelos configurados localmente antes de renderizar el selector. El backend conoce tu modelo. El frontend se niega a mostrarlo. Es un bug del cliente, no un error de config, y se abrió el 2026-04-26 y sigue abierto al escribir esto.
La segunda causa es la más común y la menos alarmante. Si solo escribiste model = "some-id" sin catálogo, Codex tiene el string pero no nombre de pantalla, ni ventana de contexto, ni flags de capacidades. El selector muestra la etiqueta "Custom" y sigue. Tus peticiones siguen yendo al modelo correcto. Esto confunde porque "Custom" parece roto cuando en realidad funciona.
CÓMO CARGA CODEX LOS MODELOS
Dónde diverge Desktop del CLI
Codex construye su lista de modelos por capas, y el orden te dice qué fix va a funcionar de verdad.
Tres fuentes alimentan la lista: un catálogo empaquetado con el binario, un catálogo remoto que se obtiene de OpenAI y tu model_catalog_json local. El archivo local gana — sobrescribe tanto al catálogo empaquetado como al remoto en el arranque, que es por lo que un model_catalog_json correcto es la palanca real para modelos de terceros, no un extra opcional.
Aquí está la parte que confunde a todos. Al arrancar, el app-server lee las tres capas, las resuelve y expone el resultado por un endpoint interno model/list. El CLI renderiza esa lista directamente, así que los modelos custom aparecen. Desktop renderiza la misma lista a través de un paso extra del cliente que, según el issue #19694, aplica su propia lista de permitidos y descarta las entradas configuradas localmente antes de que lleguen al desplegable. Mismo backend, mismo catálogo, dos selectores distintos. Esa única divergencia es por la que el CLI es una vía de escape fiable y Desktop no.
También hay una caché que vigilar. Codex mantiene ~/.codex/models_cache.json, y tras cambiar de proveedor o editar un catálogo no siempre se resincroniza. Una caché caduca puede seguir mostrando una lista antigua — o vacía — incluso con tu config correcta. Borrar ese archivo fuerza una reconstrucción limpia en el siguiente arranque, que conviene probar antes de asumir que el catálogo en sí está mal.
LOS ARREGLOS
Cómo lograr que Codex Desktop vea tus modelos
Ve de arriba a abajo. Fix 1 siempre funciona. Los siguientes hacen el selector bonito y la lista conmutable.
EL ARREGLO FIABLE
Fix 1: Pon el modelo inline (el arreglo fiable)
Este es el arreglo en el que convergió el hilo de #19694, y al que recurrir primero. Pon el string del modelo directamente en config.toml y deja que el selector diga "Custom".
# ~/.codex/config.toml (nivel de usuario, no una carpeta de proyecto) model = "tu-proveedor/tu-model-id" model_provider = "mi-gateway" [model_providers.mi-gateway] name = "mi-gateway" base_url = "https://tu-gateway.ejemplo/v1" env_key = "MI_GATEWAY_API_KEY" wire_api = "responses"
Exporta la key (export MI_GATEWAY_API_KEY=sk-... en el profile de tu shell), sal del todo de Codex Desktop y vuelve a abrirlo. El selector leerá "Custom" pero cada petición va al modelo que pusiste. Cambia el string del modelo para alternar — sin un bloque de proveedor nuevo cada vez.
Nota sobre wire_api: Codex retiró su path antiguo de chat/completions a principios de febrero de 2026 (discusión #7782); responses es ahora el único valor soportado y el por defecto cuando se omite la key. Un proveedor que siga con wire_api = "chat" falla al arrancar. Tu gateway debe exponer un endpoint Responses compatible con OpenAI en {base_url}/responses. Apunta Codex a un gateway que solo hable /chat/completions y cada petición 404 — parece un problema de modelo pero es un desajuste de protocolo.
QUE EL SELECTOR LO LISTE
Fix 2: Añade un catálogo de modelos para que el selector lo liste
Si quieres un nombre real en el desplegable en vez de "Custom", necesitas un model_catalog_json. Apunta config.toml a un archivo JSON con un array models de primer nivel; cada entrada describe un modelo.
# arriba del todo en ~/.codex/config.toml model_catalog_json = "/Users/you/.codex/my-models.json" model = "tu-proveedor/tu-model-id" model_provider = "mi-gateway"
{
"models": [
{
"slug": "tu-proveedor/tu-model-id",
"display_name": "Tu Modelo (gateway)",
"description": "Modelo de código vía el gateway",
"context_window": 262000,
"max_context_window": 262000,
"supported_in_api": true,
"visibility": "list",
"priority": 1
}
]
}El slug debe ser igual al string que envías al proveedor. El catálogo oficial lleva muchos más campos por modelo (niveles de reasoning, tipos de tools, flags de modalidad), y escribir la forma completa a mano es tedioso — que es justamente por lo que existe Fix 4. Reinicia Desktop tras cualquier cambio de catálogo. Esta capa sobrescribe tanto al catálogo empaquetado como al remoto, y solo se relee en el arranque, así que un cambio de config por hilo no la vuelve a aplicar.
ARREGLA LA CAPA DE CONFIG
Fix 3: Mueve el proveedor a la config de nivel de usuario
Si Codex imprime un warning de arranque sobre ajustes de proveedor ignorados, tu bloque de proveedor está en el archivo equivocado. model_provider y model_providers solo funcionan en ~/.codex/config.toml. Un .codex/config.toml de repo no puede definir proveedores.
# comprueba dónde vive tu proveedor realmente grep -rn "model_providers" ~/.codex/config.toml ./.codex/config.toml 2>/dev/null # si está en ./.codex/config.toml, mueve el bloque [model_providers.*] # y model_provider = "..." a ~/.codex/config.toml, y reinicia
Guarda lo específico del repo, como archivos de instrucciones, en la config del proyecto. Guarda el proveedor y el catálogo a nivel de usuario. Una advertencia: el model_catalog_json a nivel de proyecto es un caso aparte — por diseño debería seguir leyéndose, pero en hilos nuevos de Desktop actualmente no se lee, lo cual es un bug abierto (#26308) más que comportamiento intencionado.
ARREGLA LA CAPA DE HERRAMIENTAS
Fix 4: Deja que cc-switch v3.16.5 genere el catálogo
Si gestionas Codex con cc-switch, actualiza a v3.16.5 o superior. Esa release es la que arregla el selector vacío para proveedores nativos. Genera ~/.codex/cc-switch-model-catalog.json para proveedores en endpoints Responses nativos (apiFormat: "openai_responses"), que es lo que permite a Codex Desktop ver los modelos y usar las tools integradas.
- Vuelve a guardar cada proveedor nativo una vez. El catálogo solo se regenera al guardar. Los proveedores existentes conservan su estado antiguo (roto) hasta que los abres y los guardas de nuevo. No hay migración automática.
- Entiende el desacoplamiento. En v3.16.5 el catálogo de modelos ya no va atado al toggle de "local routing". Los proveedores Responses nativos ahora generan el catálogo tengas o no el local routing activado, mientras los de formato Chat siguen yendo por conversión del proxy como antes.
# confirma que el catálogo existe y lista tus modelos tras volver a guardar cat ~/.codex/cc-switch-model-catalog.json | grep -o '"slug":[^,]*' # si esto está vacío, vuelve a guardar el proveedor en cc-switch y comprueba otra vez
Una advertencia que el propio cc-switch desactiva: algunos modelos chinos de primera parte (MiMo, LongCat, MiniMax, Qwen3-Coder) no soportan el web_search integrado de OpenAI en sus gateways, así que v3.16.5 desactiva esa tool para ellos por defecto para evitar que Codex devuelva un 400 duro. Si enrutas esos a través de un gateway, espera que la búsqueda web esté apagada.
ERRORES QUE IMITAN EL BUG DEL SELECTOR
Descártalos antes de tocar el catálogo
La mitad de los reportes de "modelos custom que no aparecen" son una ruta rota disfrazada de problema de pantalla. Cada uno produce un síntoma que parece el selector ocultando tu modelo, cuando la petición nunca tuvo opción de llegar.
| Síntoma | Causa real | Fix |
|---|---|---|
| Error de arranque, o cada petición 404 | wire_api = "chat" (retirado feb 2026) o un gateway sin endpoint /responses | Pon wire_api = "responses" |
| Cada petición devuelve 401 | env_key nombrado pero la variable nunca exportada | Exporta la key en tu profile del shell |
| El modelo funciona pero devuelve salida incorrecta | El slug del catálogo no coincide con el ID del proveedor | Iguala el slug al string exacto del modelo |
| Proveedor ignorado, warning en el arranque | El bloque vive en .codex/config.toml del proyecto | Muévelo a ~/.codex/config.toml |
| Reseteos de conexión intermitentes | Barra final o path equivocado en base_url | Termina la URL en /v1, sin barra final |
La señal que separa estos del filtro real #19694 es un comando: ejecuta la misma petición desde el CLI. Si el CLI también falla, es uno de los errores de arriba, no el selector de Desktop, y ningún cambio de catálogo lo arregla. Si el CLI funciona y solo Desktop se queda ciego, es el filtro — y vuelves a Fix 1 y Fix 4.
CRONOLOGÍA DE ISSUES
Issues conocidos de modelos custom en Codex Desktop (2026)
Esto no es un solo bug. Es un cluster de issues relacionados en la app de Codex y en las herramientas que escriben su config. Saber cuál tienes te ahorra aplicar el arreglo equivocado.
| Issue | Qué rompe | Reportado | Estado |
|---|---|---|---|
| openai/codex #19694 | El selector de Desktop filtra modelos de catálogo que el backend cargó | 2026-04-26 | Abierto |
| openai/codex #26308 | Desktop ignora el model_catalog_json del proyecto en hilos nuevos | 2026 | Abierto |
| openai/codex #22160 | /model del CLI y los selectores de Desktop no exponían alias de profile / provider | 2026 | Cerrado |
| openai/codex #15364 | Sin UI para elegir un proveedor custom dentro de la app Desktop | 2026 | Cerrado |
| cc-switch #3668 | Formato de catálogo de cc-switch no reconocido, /model vacío | 2026-06-03 | Arreglado en v3.16.5 |
El patrón en todos estos: el enrutamiento funciona, la pantalla no. El CLI ha sido la vía de escape fiable cada vez, porque lee el catálogo sin el filtro extra del renderer de Desktop. Si estás bloqueado en Desktop, el CLI (codex en tu terminal) casi siempre mostrará y usará el modelo.
CUANDO EL SELECTOR SIGUE SIN MOSTRAR
Alternativas que funcionan ahora
Si estás cansado de pelear con la UI de Desktop, aquí hay formas de seguir usando modelos custom sin esperar un arreglo del cliente.
| Camino | Cómo llega el modelo a Codex | Comportamiento del selector | Notas |
|---|---|---|---|
| CLI de Codex | Misma config, cliente de terminal | Lista modelos custom de forma fiable | Evita el filtro de Desktop |
| Un gateway unificado | Un base_url, una key, muchos IDs de modelo | "Custom" o listado por catálogo | Cambia modelos con un string |
| Key directa de proveedor | Un bloque de proveedor por fabricante | El mismo filtro aplica | Más keys, más bloques que mantener |
| Local (Ollama) | base_url en localhost | Warnings salvo que haya catálogo | Offline, sin gateway |
El sentido de un gateway aquí es un endpoint y una key para muchos modelos, de modo que cambiar de modelo es editar un string en vez de un bloque de proveedor nuevo cada vez. Sea cual sea el camino, la rareza del selector de Desktop es una capa de pantalla por encima, no una restricción de enrutamiento.
VERIFICA
Cómo confirmar que tus modelos están cargados de verdad
No confíes en el selector como fuente de verdad — es justo lo que está roto. Verifica en la capa por debajo.
codex --version # confirma que estás en un build reciente codex # arranca el CLI y escribe /model # el CLI enumera el catálogo sin el filtro de Desktop
Si /model en el CLI muestra tu modelo, el catálogo y el proveedor son correctos y cualquier hueco restante es el renderer de Desktop. Si el CLI también sale vacío, el problema está aguas arriba: archivo equivocado (Fix 3), catálogo mal formado (Fix 2 / Fix 4) o un slug malo. Para una comprobación rápida de que la ruta resuelve, un curl contra el gateway con tu key te dice si el modelo existe antes de culpar al cliente. Primero la ruta, luego la pantalla.
LO QUE ESTO ENSEÑA DE VERDAD
La fiabilidad de tus herramientas no debería depender de un filtro de UI
Los arreglos de arriba te devuelven el selector. El resto es la parte por la que vale la pena actuar antes del próximo bug.
Puedes leer este bug de dos formas. La estrecha: un cliente de Desktop filtra tus modelos, ponlos inline y sigue. La útil: una herramienta que tratabas como parte de tu flujo soltó funcionalidad en la capa de renderizado, y la única señal fue que el desplegable se veía vacío.
Lo vemos en casi todo sistema de IA que auditamos. Un equipo construye sobre un cliente, una UI, un modelo por defecto, y un bug, una deprecación o un filtro silencioso convierte un setup que funcionaba en media tarde de conjeturas. El bug del selector de Codex es solo la versión más reciente y más concreta.
Tres cosas hacen que un setup sobreviva a estos cambios:
Verifica en la capa por debajo de la UI
No confíes en el selector. Confía en el endpoint, el CLI, el curl. La pantalla es lo último en lo que creer y lo primero en romperse.
Desacopla el modelo de la herramienta
Un string de config cambia el modelo; un gateway cambia el proveedor. Cuando un cliente filtra o un proveedor depreca, tu integración es un cambio de config, no una reescritura.
Diseña para el bug, no para la demo
Asume que toda UI de cliente tiene un filtro que no ves y que todo camino gratuito tiene fecha de caducidad. Construye la vía de escape antes de necesitarla.
Si tu flujo colapsa cuando un cliente oculta un modelo, el flujo suspendió el examen de diseño — no el cliente.
FAQ
Preguntas que nos hacen sobre esto
¿Por qué Codex Desktop no muestra mis modelos custom?+
Normalmente el modelo funciona y la app de Desktop lo está filtrando del selector (issue #19694). Causas secundarias: ningún archivo de catálogo, un catálogo mal formado de una herramienta antigua, o un proveedor definido en un .codex/config.toml del proyecto.
¿Cómo añado un modelo custom al config.toml de Codex?+
Define [model_providers.NAME] con base_url, env_key y wire_api, luego pon model_provider y model. Mantenlo en ~/.codex/config.toml. Para un gateway, base_url termina en /v1 sin barra final.
¿Funciona cc-switch con Codex Desktop?+
Sí, desde v3.16.5, que genera ~/.codex/cc-switch-model-catalog.json para proveedores Responses nativos. Vuelve a guardar cada proveedor una vez tras actualizar — el catálogo solo se regenera al guardar.
¿Dónde está el archivo de catálogo de modelos de Codex?+
Donde apunte model_catalog_json en ~/.codex/config.toml. cc-switch usa ~/.codex/cc-switch-model-catalog.json. Vigila una caché caduca ~/.codex/models_cache.json tras cambiar de proveedor — bórrala para forzar una reconstrucción limpia.
¿Por qué Codex muestra "Custom" en vez del nombre de mi modelo?+
Pusiste model inline sin entrada de catálogo, así que el selector no tiene metadatos de pantalla. Las peticiones siguen yendo al modelo correcto. Añade un model_catalog_json (Fix 2) para darle un nombre real.
¿Puedo usar modelos custom en un .codex/config.toml del proyecto?+
No. Los ajustes de proveedor solo aplican en ~/.codex/config.toml. Los bloques de proveedor a nivel de proyecto se ignoran con un warning de arranque. Mantén el proveedor a nivel de usuario; guarda las instrucciones específicas del repo en la config del proyecto.
¿Qué es model_catalog_json en Codex?+
Una clave de config.toml que apunta a un archivo JSON, cargado en el arranque, con un array models de primer nivel de entradas con slug, display_name y campos de capacidades. Sobrescribe tanto al catálogo empaquetado como al remoto.
¿Qué es wire_api y por qué importa?+
Selecciona el protocolo de petición. Codex retiró el path de chat/completions a principios de febrero de 2026; responses es ahora el único valor soportado y el por defecto. Un proveedor puesto en chat falla al arrancar, y un gateway sin endpoint /responses devuelve 404 en cada petición.
Sobre FACTA
FACTA ayuda a startups y equipos en etapa de crecimiento a convertir IA en sistemas de producción que siguen funcionando — no demos que impresionan una vez.
Diseñamos la arquitectura en torno a lo que de verdad se rompe bajo uso real: abstracción de modelo, credenciales que te pertenecen, failover, controles de coste, observabilidad. La infraestructura aburrida que mantiene un sistema vivo después del lanzamiento.
Liderado por Matías Baglieri y Carolina Fogliato, nos centramos en una sola cosa:
Liderazgo de IA que construye. No solo asesora.
Deja de apagar fuegos de tooling. Automatiza la capa.
Cuando una UI de cliente descarta silenciosamente tus modelos, el arreglo rara vez es una edición más de config — es una capa de automatización que mantiene tu tooling fiable, observable y desacoplado de cualquier cliente concreto. FACTA diseña y construye esa capa para que tu flujo sobreviva al próximo filtro, deprecación o cambio que rompa.
Explorar Automatización de IA