Skip to content

Troubleshooting

Most failures in a new setup have a known cause and a fix, grouped by the step where they appear. Logs and files says where gmlx writes its logs, runfiles, caches and sessions.

Run gmlx doctor first. It checks each part of a working setup, and it names the fix for each check that fails. For a coding agent or chat app that does not connect, read its entry under The clients.

Installing

The install fails on macOS before 26.2

gmlx needs macOS 26.2 or newer, because mlx-kquant's Metal kernels are built for that version. On an earlier version, the install fails or the kernels cannot run. gmlx doctor prints the macOS version and warns below 26.2. Update macOS in System Settings, then install gmlx again.

gmlx: command not found in a new terminal

The command worked in an earlier terminal, but a new one says command not found: gmlx. This happens only with the pip route, where gmlx lives in a Python venv that each new terminal starts with inactive. Run source <install dir>/.venv/bin/activate to get the command back. A background server or the menu bar app keeps running either way. An install through Homebrew or uv tool install stays on PATH in every terminal.

A feature says its extra is not installed

Voice chat stops with voice chat requires the optional talk extra, or speech on the server or the assistant's MCP tools report a missing extra in the same way. These features come in optional extras. The message gives the install command for your kind of install, and the feature works once that command finishes.

Downloading and loading models

A download was interrupted or the disk filled

gmlx pull stopped partway, or refused to start with error: not enough disk space. A dropped connection retries by itself with backoff, from the bytes already on disk. Raise GMLX_PULL_RETRIES for a flaky host, and GMLX_PULL_TIMEOUT for a slow one. An interrupted pull resumes when you run the same command again, because the bytes so far stay in a .part file beside the destination.

The disk check names how much space the file needs and how much is free. Free some space, pass --to DIR for another volume, or pass --force to skip the check.

A pull reports a stale partial download

The pull stops with stale partial download: <file>.part has N bytes but the remote file is M. The repo replaced the file after the earlier attempt, so the partial bytes belong to an older version. Delete the .part file it names, and the next pull fetches that file from the start.

A gated or private repo will not download

gmlx validate or gmlx pull gets a 401 or 403 from Hugging Face. gmlx sends the Hugging Face token that the command environment variables describe. Accept the repo's terms on its Hugging Face page, and check that this token has access to it.

A load says the file is incomplete or truncated

A load stops with incomplete split GGUF: N/M shard(s) missing, or with truncated GGUF and the size the file should have. The download did not finish. The same gmlx pull fetches a missing shard, but it skips a file that already exists, so delete a truncated file before you pull it again.

The architecture is not supported

A load stops with GGUF architecture 'X' is not supported. gmlx maps each model architecture to code that runs it, and this file's architecture has no mapping. Supported architectures lists the ones that do. gmlx validate shows the architecture before you download.

A file refuses to load with an unsupported codec

validate, pull or a load names a tensor type with no kernel, which validate marks <- no kernel. The K-quant, legacy, IQ, MXFP4 and NVFP4 types all have kernels, as do the ternary STQ1_0 and PTQ1_0 types and the 2-bit PQ2_0 type. The usual cause is the plain ternary TQ1_0 or TQ2_0 type.

Pick another quant from the same repo. gmlx validate hf:<org>/<repo> lists the files so that you can choose without downloading. A uniform K-quant also decodes fastest.

A Hadamard-folded file refuses to load

A load stops with is Hadamard-folded and names the fold version. Such a file stores its weights under a rotation that gmlx undoes at run time only for fold version 1 on the qwen35 architecture, which covers the dense Qwen3.5, 3.6 and 3.8 models. Any other folded file is refused before a tensor is read, and so is a folded drafter.

gmlx validate prints a weights: Hadamard-folded line for such a file. Read that line before you download, because the loadable verdict below it does not cover the fold. Pick an unfolded quant of the same model instead. The file contract is in Hadamard-folded GGUFs.

Starting the server

gmlx serve finds no config

Started in the background with no config in the default locations, gmlx serve prints note: no config found and serves a discovery scan of the directory you started it from, which may hold no GGUFs. Run gmlx init --models-dir DIR to write a config, or pass --models-dir DIR. gmlx sync-models has no such fallback and stops with no config found in the default locations.

gmlx status reports 0 models served

The server is up, but every request gets a 404. Either the config lists no models, or every entry was skipped at startup. The log shows a [server] skipping model line for each entry whose file is missing, and a [server] model_dirs root missing line for each folder in server.model_dirs that does not exist. A relative folder resolves against the directory the server started from, so use absolute paths.

Binding another address refuses to start

gmlx serve --host 0.0.0.0 stops with binding 0.0.0.0 exposes this server beyond localhost. A server reachable from the network needs a key. Set server.api_key, or pass --no-auth when a reverse proxy in front handles authentication.

A config with served assistants also stops with exposes the assistant tool loop beyond localhost, because anyone with the key could run tools on the Mac. Bind a loopback address, remove server.assistants, or set server.assistant_allow_remote if you accept that risk.

Port 8080 is already in use

serve cannot bind its port, or requests reach some other program. gmlx status shows whether a gmlx server already holds the port. If one does, run gmlx stop, or gmlx restart after a config change. A server that gmlx service install set up comes back at login, so remove it with gmlx service uninstall. For another program, lsof -i :8080 names it. Free the port, or serve on another one with --port 8081.

gmlx status says the source changed on disk

gmlx status prints source changed on disk since this server started under the status line. gmlx was upgraded, or its checkout switched, while the server kept running the old code. Requests can fail with import errors until you run gmlx restart.

The first request after startup is slow

The server answered at once, but the first reply took many seconds, because that request loaded the model. At startup the server loads every pinned model, else server.defaults.model, else the only configured model. With several models and neither setting, pin the ones to keep loaded, or list the ones to load in server.defaults.preload. A slow first turn on a long prompt is prefill instead, which the prompt cache shortens on later turns.

Requests

A request names a model the server does not have

The server answers 404 of type model_not_found, with the ids it serves in available_models, and it never downloads on a request. Use an id from gmlx list, or fetch the model with gmlx pull, which registers it when it lands under a model_dirs folder. A file saved elsewhere with --to needs gmlx sync-models --models-dir DIR or a models entry.

A suffix such as @coding that names no intent or profile gets 400 of type unknown_profile, which lists the valid names. A 403 of type hf_access_disabled is rare, and Hugging Face policy explains when it happens.

A configured model gets 404 model_file_missing

An id from your config is not listed, or a request for it gets 404 of type model_file_missing, and the log shows [server] skipping model '<id>'. The GGUF was deleted, moved or renamed, so the server skipped it and kept serving the rest. Restore the file and the id works again with no restart. If the file is gone for good, gmlx sync-models removes its entry.

A missing server.embeddings or server.rerank file disables that service with a warning, and its route answers a plain 404 with no error type. That service stays off until gmlx restart, even after the file comes back. A service file set by an absolute path is the exception. When that file is missing, its route answers 404 of type model_file_missing until the file is back, and then works with no restart.

A model answers as if the message were empty

Replies ignore what you sent, the log shows the chat template of <file> drops message text at load, and a request with a system prompt can fail with 500. For Qwen3.5 and other model types that also accept images, the server passes each message to the chat template as a list of parts. Some fine-tunes ship an older template that renders only plain strings, so every message arrives empty.

Replace the template with one that renders lists, usually the base model's template. Pass the file with --chat-template on gmlx serve, or set chat_template in a profile or in the model's overrides.

Requests get 503

A 503 carries a Retry-After header, and its error type says why:

Type Cause What to do
server_overloaded More requests are waiting than the queue cap. Retry after the given delay, or raise GMLX_QUEUE_DEPTH_CAP.
model_load_deferred The model cannot load beside the resident models that are busy. Retry after the delay, or lower what stays resident.

Limits and back-pressure has every limit a request can hit, including the 400 for a prompt that cannot fit.

A streamed reply ends with server_overloaded_shed

A streaming reply stops early with an error of type server_overloaded_shed, code row_shed and finish_reason shed. The memory governor ran out of other ways to free memory, so it shed this request to keep the others running. Send it again, and read Memory if it happens often.

Memory

The Mac swaps, or a load or reply fails for memory

The whole Mac slows while a model runs, or a command stops with an error. On run and chat, a context that cannot fit is refused before the load with cannot fit: and the numbers. A context that grows past memory during the reply stops with out of GPU memory mid-run. Both show how much the model needs and what the GPU may use.

In each case, the weights plus the KV cache need more memory than the GPU may use. Memory and the KV cache shows how to estimate both and which settings reduce them. The usual fixes are a quantized KV cache, a smaller context, a smaller quant, or streaming for a MoE model larger than memory. On a server with several models, lower server.budget_gb or server.max_models. To try anyway, set GMLX_TOOL_PREFLIGHT=0, which skips the refusal on run and chat.

Voice

The mic never works in talk

gmlx talk runs but never hears you, and macOS never showed a permission prompt. macOS grants the microphone to the terminal app that you ran talk from. In System Settings, open Privacy and Security, then Microphone, and turn on your terminal, whether Terminal, iTerm2 or your editor. If you dismissed the prompt long ago, turn the entry off and on to get a new one. gmlx talk --list-devices shows whether any input device is visible.

Transcription or speech fails because ffmpeg is not found

/v1/audio/transcriptions, or speech in mp3, flac or opus, answers 500, and the request line in the server log names the cause. Transcription logs audio decoding needs ffmpeg on PATH, and speech logs ffmpeg not found. Whisper decodes its input through ffmpeg, and speech needs it for every format except wav and pcm. Run brew install ffmpeg, then gmlx restart.

Distillation

A distill step fails or the adapter learns nothing

gmlx distill filter drops most rows, align warns or refuses, the census effect is small, train runs out of memory, or the served adapter scores near zero. When something goes wrong in the distillation guide covers each case, and gmlx distill lists every action's exit codes.

Logs and files

Where the logs are

gmlx logs -n 100 prints the last lines of the background server's log, and -f follows it. Each finished request logs a line with the model, the token counts and the timing, which is often enough to see what was slow. gmlx status reports the process, and gmlx ps lists the resident models. gmlx serve --print-config prints the full config the server would run with.

Where files are on disk

gmlx writes to these places. Paths under ~/.cache and ~/.local/share follow XDG_CACHE_HOME and XDG_DATA_HOME when they are set.

Path Contents
./gmlx.yaml, ~/.config/gmlx/gmlx.yaml, ~/.gmlx.yaml These hold the config, as Where gmlx looks describes.
~/.config/gmlx/ gmlx launch writes injected clients' configs here.
~/.pi/agent/, ~/.omp/agent/, ~/.config/goose/config.yaml gmlx launch merges its settings into these files, as The clients describes. To remove gmlx, delete those settings and keep the files.
~/.cache/gmlx/ It holds server runfiles and logs, chat input history and the GGUF header cache.
~/.cache/gmlx/apc/ The prompt cache is stored here when the disk tier is on and has no path of its own.
~/.cache/gmlx/talk/ The first talk fetches the wake-word and voice-activity models here.
~/.cache/huggingface/ hf: references resolve from these files.
~/.local/share/gmlx/chats/ Saved chat sessions are kept here.
~/.local/share/gmlx/assistant-memory.db It holds the assistant's memory, with assistant-<id>.db beside it for each served assistant.
~/Library/Application Support/gmlx/ The menu bar runs from an app bundle that gmlx writes here.
~/Library/LaunchAgents/com.gmlx.*.plist gmlx service install writes its login items here.
~/.open-webui/ Open WebUI keeps its chat history here.
Your model folders pull downloads GGUFs into them.

Removing gmlx gives the steps that remove gmlx and these files.