En pocas palabras: Sí: en Ollama 0.35.1, cuando un modelo usa el chat path nativo (por ejemplo con OLLAMA_GO_TEMPLATE=false), la función llamaServerChatResponseFormat() reordena alfabéticamente las claves del JSON schema antes de enviarlo a llama-server. Esto invirtió “colour” y “animal” en Gemma 3 1B, según el reporte ollama/ollama#18717 del 30 de septiembre de 2026. El fix propuesto es ollama/ollama#18721.
Ollama 0.35.1 tiene un bug confirmado que afecta a las salidas estructuradas: cuando un modelo corre por el “chat path nativo”, la función llamaServerChatResponseFormat() reordena alfabéticamente las claves de tu JSON schema antes de mandarlo a llama-server. El reporte ollama/ollama#18717, publicado el 30 de septiembre de 2026, muestra a Gemma 3 1B devolviendo los valores de “colour” y “animal” invertidos por este problema de orden de claves json en Ollama.
Ollama es el runtime open source para correr modelos de lenguaje en local, y resuelve las salidas estructuradas (structured outputs) pasando el schema JSON a llama-server para que genere una respuesta válida contra ese esquema. El “chat path nativo” es una de las dos rutas internas que usa Ollama 0.35 para armar esa petición, y es justo ahí donde el orden de las claves se pierde.
En este artículo:
- En 30 segundos
- ¿Qué es el “chat path nativo” de Ollama y en qué se diferencia del renderizado por plantilla Go?
- ¿Qué condiciones activan el bug de orden alfabético?
- ¿Cómo se comprobó el error paso a paso?
- ¿Qué significa que Ollama reordene alfabéticamente las claves json y por qué el JSON sigue siendo “válido”?
- ¿Cuál es la causa técnica en el código de Ollama?
- ¿Cómo saber si un modelo instalado está afectado?
- ¿Cómo evitar el problema hasta que salga el fix oficial?
- Qué está confirmado y qué no
- Errores comunes al lidiar con este bug
- Preguntas Frecuentes
- Conclusión
- Fuentes
En 30 segundos
- Ollama 0.35.1 reordena alfabéticamente las claves de un JSON schema cuando el modelo pasa por el chat path nativo, según documentó el análisis de homelabpm en dev.to.
- Con el servidor corriendo con
OLLAMA_GO_TEMPLATE=false, Gemma 3 1B devolvió{"alpha_animal": "blue", "zeta_colour": "zebra"}en vez del orden declarado. - Los cuatro modelos probados en configuración default (incluidos dos imports de Hugging Face) mantuvieron el orden correcto porque usaron el path renderizado con plantilla Go.
- El problema es regresión de un fix de diciembre de 2024, ollama/ollama#8002, que ya había resuelto exactamente esto.
- El PR ollama/ollama#18721 propone la solución y restauró el orden en una build de prueba, pero todavía no está en un release oficial.
¿Qué es el “chat path nativo” de Ollama y en qué se diferencia del renderizado por plantilla Go?
El chat path nativo es la ruta que usa Ollama cuando un modelo no tiene plantilla Go propia, y ahí la diferencia con el otro camino es la clave de todo este problema. En server/routes.go, la función chatModeForModel() decide el camino con una lógica simple: si el modelo es MLX o pasa usesOllamaRenderedChat(), va por el modo renderizado. Si no, va por el nativo.
El modo renderizado mantiene el schema como json.RawMessage y lo pasa tal cual a llama-server, sin tocar una coma. El nativo, en cambio, llama a llamaServerChatResponseFormat(), que decodifica el schema a un map[string]any de Go y lo vuelve a codificar. Ahí está el problema: Go no guarda orden en un map, y encoding/json escribe las claves en orden alfabético cuando serializa. El schema entra con el orden que vos declaraste y sale alfabetizado, sin que nadie lo pida. Esto se conecta con lo que analizamos en nuestra guía sobre montar un entorno local sin root.
¿Qué condiciones activan el bug de orden alfabético?
Un modelo cae en el chat path nativo por tres caminos distintos, y solo uno de ellos quedó reproducido en el reporte. El primero es que el modelo no tenga plantilla Go en absoluto. El segundo es que Ollama prefiera la plantilla del propio GGUF por encima de la Go, algo que pasa cuando esa plantilla soporta más funciones, tool calling por ejemplo. El tercero, el único que el reporte de homelabpm logró confirmar en la práctica, es correr el servidor con la variable OLLAMA_GO_TEMPLATE=false.
Ojo con esto: en una instalación default, los cuatro modelos probados (un Gemma 3 1B plano, dos imports de hf.co y un Qwen3:0.6b de la librería) evitaron el bug porque todos traían plantilla Go. El bug no aparece “siempre que usás structured outputs”. Aparece en combinaciones específicas, y eso es justo lo que lo hace difícil de detectar.
¿Cómo se comprobó el error paso a paso?
La prueba se hizo en un contenedor Debian 13 LXC, solo CPU, con Ollama 0.35.1 instalado desde el tarball oficial de release. El schema declaraba dos claves en orden inverso al alfabético, zeta_colour primero y alpha_animal después, y el prompt era “Name a colour and an animal” a temperatura 0, enviado tanto por /api/chat (con format) como por /v1/chat/completions (con response_format).
En el servidor default, los cuatro modelos devolvieron el orden declarado sin problema. Reiniciado el mismo servidor con OLLAMA_GO_TEMPLATE=false, Gemma 3 1B respondió { "alpha_animal" : "blue", "zeta_colour" : "zebra" }. Las claves salieron en orden alfabético, y los valores quedaron en el campo equivocado: “blue” terminó en el campo del animal y “zebra” en el del color. Tema relacionado: nuestra guía completa de IA local.
¿Qué significa que Ollama reordene alfabéticamente las claves json y por qué el JSON sigue siendo “válido”?
Significa que la respuesta cumple el schema y la API devuelve HTTP 200, pero el contenido de cada campo puede estar mezclado con el de otro. El modelo respondió “a colour and an animal” en el orden que pedía la pregunta, mientras la grammar de llama-server, armada a partir del schema ya reordenado, forzó a completar alpha_animal primero. El resultado es JSON técnicamente correcto con datos cruzados adentro.
¿Y por qué nadie lo nota en el testeo normal? Porque un parser que lee por nombre de clave no reporta error, y la mayoría de los tests de structured outputs solo chequean que el JSON parsee contra el schema. Un patrón muy común en prompting es declarar reasoning antes de answer para que el modelo razone antes de comprometerse a una respuesta. Alfabetizado, answer queda primero. La petición se ve normal, la respuesta se ve normal, y el único síntoma real es que las respuestas son peores sin que nada lo señale.
¿Cuál es la causa técnica en el código de Ollama?
La causa está en llm/llama_server.go, en la función que construye el response_format para el path nativo. El código decodifica el schema con var schema map[string]any y json.Unmarshal, y después lo vuelve a empaquetar dentro de un objeto con "type": "json_schema". Esa decodificación a un tipo de Go que no guarda orden es el punto exacto donde se pierde la secuencia original de claves. Te puede servir nuestra cobertura de un agente IA local gratuito.
- Path renderizado: guarda el schema como
json.RawMessagey lo pasa intacto a llama-server, sin decodificar nada. - Path nativo: decodifica a
map[string]any, pierde el orden, yencoding/jsonlo reescribe alfabetizado al codificar de nuevo.
Lo llamativo es que este problema ya se había resuelto antes. En diciembre de 2024, el PR ollama/ollama#8002 (“preserve field order in user-defined JSON schemas”) cerró exactamente esta misma queja, cambiando el código para usar json.RawMessage directo en vez de decodificar y reencodear. El runner de llama-server, en algún punto posterior, volvió a introducir el paso que pierde el orden. Es una regresión en el sentido más literal: algo que ya estaba arreglado, se rompió de nuevo.
| Modelo | Path tomado | Orden con servidor default | Orden con OLLAMA_GO_TEMPLATE=false |
|---|---|---|---|
| Gemma 3 1B (FROM gguf) | Renderizado / Nativo según flag | Correcto (zeta_colour, alpha_animal) | Alfabético, valores cruzados |
| Qwen2.5-0.5B (hf.co/bartowski) | Renderizado / Nativo según flag | Correcto | Alfabético |
| LFM2-350M (hf.co/LiquidAI) | Renderizado / Nativo según flag | Correcto | Alfabético |
| Qwen3:0.6b (librería) | Renderizado (Go template) | Correcto | No reproducido en el reporte |

¿Cómo saber si un modelo instalado está afectado?
El método de diagnóstico es mandar un schema de dos claves en orden inverso al alfabético y mirar cuál sale primero en la respuesta. Si declarás zeta_x antes de alpha_y y la salida trae alpha_y primero, ese modelo está pasando por el chat path nativo y perdiendo el orden. Una sola petición alcanza, y no depende de que sepas de memoria las reglas de routing de Ollama.
El toolkit del propio reporte incluye un script llamado check-ollama-schema-order.sh, que automatiza justo esto: le manda el schema de prueba a cada modelo instalado (o a los que vos le indiques) y reporta cuáles mantienen el orden declarado. También lee la variable OLLAMA_GO_TEMPLATE del entorno del servidor corriendo. Si tenés esa variable en false, la recomendación del propio análisis es asumir que todo modelo sin renderer propio está afectado, sin necesidad de testear uno por uno.
¿Cómo evitar el problema hasta que salga el fix oficial?
El workaround que propone el reporte es nombrar tus claves para que el orden alfabético coincida con el orden que realmente querés. Si tu patrón es razonamiento antes de respuesta, en vez de reasoning y answer usá algo como a_reasoning y b_answer. Alfabetizado o no, el orden queda igual. Cubrimos ese tema en detalle en reducir costos de API corriendo modelos en local.
- Renombrá con prefijos ordenados:
a_colourantes deb_animalda el mismo resultado en ambos paths, sin depender de qué camino tome el modelo. - Testeá antes de confiar: mandá el schema de dos claves en reversa alfabética y confirmá el comportamiento real en tu instalación, no asumas por la documentación.
- Revisá tu config de
OLLAMA_GO_TEMPLATE: si la tenés enfalsepor algún motivo, es la variable con más chances de meterte en el chat path nativo.
El fix real ya existe como propuesta: el PR ollama/ollama#18721 cambia la función para pasar el schema recortado como json.RawMessage en vez de decodificarlo a un map. Probado sobre una build de 0.35.1 con el parche aplicado, y con el mismo servidor en OLLAMA_GO_TEMPLATE=false, Gemma 3 1B volvió a devolver {"zeta_colour": "blue", "alpha_animal": "dolphin"}, con el orden declarado y los campos en su lugar. El PR estaba abierto al momento de este reporte, sin fecha confirmada de merge ni de inclusión en un release estable.
Qué está confirmado y qué no
- Confirmado: el bug existe en Ollama 0.35.1 y también se reprodujo en 0.33.2, según el reporte original en GitHub.
- Confirmado: la causa es
llamaServerChatResponseFormat()enllm/llama_server.go, decodificando amap[string]any. - Confirmado: es regresión del fix de diciembre de 2024 en ollama/ollama#8002.
- Pendiente: el PR #18721 todavía no está mergeado ni incluido en un release oficial al momento de escribir esto.
- Pendiente: no hay confirmación de cuántos modelos en producción real están tomando el chat path nativo sin que el usuario lo sepa, porque depende de si cada GGUF trae o no plantilla Go.
Errores comunes al lidiar con este bug
- Asumir que probaste “todos los casos” con un solo modelo: el bug no aparece en todos los modelos por igual, depende de si tienen plantilla Go. Probar con Llama 3 y asumir que Gemma se comporta igual es el error típico.
- Testear solo con schemas de una clave: si tu schema tiene una sola propiedad, nunca vas a ver el bug. Necesitás al menos dos claves en orden no trivial para detectarlo.
- Confiar en que “el JSON parseó bien” significa que está correcto: parsear contra el schema no garantiza que los valores estén en el campo que corresponde, como mostró el caso de Gemma con colour y animal invertidos.
- No revisar si tenés
OLLAMA_GO_TEMPLATE=falseseteada: es una variable de entorno que mucha gente configura por otro motivo (compatibilidad con cierto chat template) y se olvida que también cambia el routing del schema.
Preguntas Frecuentes
¿Por qué Ollama reordena alfabéticamente las claves del JSON schema?
Porque la función llamaServerChatResponseFormat() decodifica el schema a un map[string]any de Go antes de mandarlo a llama-server, y los maps de Go no guardan orden. Al reencodear ese map con encoding/json, las claves salen ordenadas alfabéticamente, sin que haya una intención de diseño detrás.
¿Qué modelos de Ollama están afectados por este bug?
Están afectados los modelos que entran al chat path nativo: los que no tienen plantilla Go, los que usan la plantilla del propio GGUF por tener funciones extra como tool calling, y cualquier modelo corriendo en un servidor con OLLAMA_GO_TEMPLATE=false. En configuración default, modelos con plantilla Go (incluidos imports de Hugging Face) no se ven afectados.
¿Qué es OLLAMA_GO_TEMPLATE y cómo afecta el formato de salida?
OLLAMA_GO_TEMPLATE es una variable de entorno del servidor Ollama que controla si se usa la plantilla Go para renderizar el chat. Puesta en false, fuerza a los modelos sin otra razón para usar el chat path nativo, el camino donde se pierde el orden de claves del JSON schema.
¿Cómo sé si mi modelo en Ollama entrega las claves en el orden correcto?
Mandale un schema con dos claves declaradas en orden inverso al alfabético y revisá cuál aparece primero en la respuesta. Si sale en el orden que declaraste, tu modelo va por el path renderizado; si sale alfabetizado, está en el path nativo y afectado por el bug.
¿Ya existe un fix oficial para este bug de Ollama?
Existe una propuesta de fix, el PR ollama/ollama#18721, que pasa el schema como json.RawMessage sin decodificarlo, y en pruebas restauró el orden correcto. Al momento de este reporte seguía abierto, sin confirmación de merge ni de inclusión en un release estable de Ollama.
Conclusión
El tema de fondo no es un bug aislado de Ollama, es una lección sobre capas intermedias: cualquier componente que decodifica tu request a su propio tipo de datos y lo vuelve a codificar se queda solo con lo que ese tipo puede representar. Un map de Go no representa orden, así que el orden ya estaba perdido antes de que llama-server viera el schema. Esto venía de arrastre desde 2024, se arregló, y volvió sin aviso en 0.35.1.
Si usás structured outputs con Ollama en algo que importe, especialmente patrones de razonamiento antes de respuesta, la jugada práctica es simple: nombrá las claves para que el orden alfabético y tu orden deseado sean el mismo, y testeá con un schema de dos claves en reversa para confirmar qué camino está tomando tu modelo en tu servidor puntual. El PR #18721 soluciona la causa raíz cuando se mergee, pero hasta entonces el riesgo está activo.
