Troubleshooting

Start with the logs. Decidealot writes JSON lines to stderr, so docker logs decidealot shows them. Each line has time, level, msg and structured fields such as provider, status_code and request_id. Set DECIDEALOT_LOG_LEVEL=DEBUG for health-check and routing detail.

Startup refusals

Configuration is checked before anything else. An invalid value stops the process with a pydantic ValidationError for Settings that names the field, and the container exits.

Message Cause Fix
DECIDEALOT_CLM_EMBEDDINGS_URL is required when CLM is enabled DECIDEALOT_CLM_ENABLED=true without a URL. Set the URL, or set DECIDEALOT_CLM_ENABLED=auto or false.
DECIDEALOT_TYPESAFE_API_KEY is required when Jev is enabled DECIDEALOT_JEV_ENABLED=true without a key. Supply the key, or set DECIDEALOT_JEV_ENABLED=auto or false.
at least one provider must be enabled Laya and Von are disabled, and neither CLM nor Jev is configured. Enable a local provider or configure CLM or Jev.
DECIDEALOT_DEVICE must match the installed image variant DECIDEALOT_DEVICE differs from DECIDEALOT_IMAGE_VARIANT. Remove both overrides; each image sets them. Use the -cuda image for CUDA.
DECIDEALOT_IMAGE_VARIANT must match the installed image variant The variant override disagrees with the image. Remove the override.
must be an absolute HTTP URL, must not contain credentials, must not contain a query or fragment DECIDEALOT_CLM_EMBEDDINGS_URL is malformed. Use a plain http:// or https:// URL to the /v1/embeddings path and put the token in DECIDEALOT_CLM_EMBEDDINGS_API_KEY.
must be a non-empty comma-separated allowlist An MCP allowlist is empty or has an empty entry, such as a trailing comma. Remove the variable to use the default, or list every value.

Numeric settings outside their range fail the same way with pydantic’s own message, such as Input should be less than or equal to 3. Configuration lists every range.

The model download fails or never finishes

Before it listens, Decidealot prepares every enabled local bundle in turn and logs preparing local provider bundle and local provider bundle prepared for each. Nothing answers on port 8080 during that time, so curl reports a refused connection and Docker reports the container as starting. The image healthcheck allows 900 seconds before it counts failures.

If preparation fails, Decidealot logs local provider bundle preparation failed with the provider and return code, and the process exits. The provider’s own error is printed just above it:

Error Fix
configured model directory must be writable to download missing files The host directory mounted at /models is not writable by the container user. Create it as the user you pass with --user, or fix its ownership.
create local model directory for <provider> or local model directory for <provider> must be readable Same cause, at the provider subdirectory.
download model repository <repository>@<revision> or download pinned CLM projection head Hugging Face could not be reached or refused the download. Check outbound HTTPS from the container, then restart it. Files already downloaded are kept.
Laya bundle is missing required files: ... or Von model is missing required files: ... The download finished without every required file. Delete that provider’s subdirectory under the model directory and restart.
CLM checkpoint digest does not match the pinned release The CLM file on disk is not the pinned release, even after a forced download. Delete clm/ under the model directory and restart.

A Jev-only deployment downloads nothing and starts in seconds.

503 PROVIDER_UNAVAILABLE

The message field says which case it is.

Message Cause and fix
<provider> provider did not become ready before the timeout The local provider process did not answer its health check within DECIDEALOT_PROVIDER_START_TIMEOUT_SECONDS. Loading a model on a slow disk or a busy host can take longer; raise the timeout.
<provider> provider stopped before becoming ready The provider process exited while loading. The provider’s traceback is in the logs just above. Common causes are memory limits (--memory) and a missing GPU on the CUDA image.
start <provider> provider The provider command could not be executed. This points at a damaged image; pull it again.
the selected provider timed out One call took longer than DECIDEALOT_REQUEST_TIMEOUT_SECONDS.
the selected provider is unavailable The provider closed the connection or answered with a 5xx. For CLM this includes an embeddings endpoint that is down, times out after DECIDEALOT_CLM_EMBEDDINGS_TIMEOUT_SECONDS, rejects the request or returns vectors of the wrong width.
the selected provider returned an invalid response The provider answered with a body that does not match the TypeSafe response shape, or with an unexpected status. For Jev this includes a rejected DECIDEALOT_TYPESAFE_API_KEY.
the hosted model catalog is unavailable or the hosted model catalog is invalid TypeSafe’s GET /v1/models failed, rejected the key, or returned something unexpected. Local selectors keep working. Check the key and TypeSafe’s status.
local providers are not ready The service is shutting down.

409 PROVIDER_BUSY

POST /v1/models/unload and the unload_models tool refuse to unload anything while a local provider is answering a request, with a local provider is processing a request. Retry when the request finishes. Decisions never return 409; they wait for a free slot instead.

413 REQUEST_TOO_LARGE

The Content-Length of the request is above DECIDEALOT_MAX_REQUEST_BYTES. Split a large batch or raise the limit, up to 16777216.

422 validation errors

The body is the TypeSafe {"detail": [...]} envelope, and loc points at the field.

msg Fix
Value error, unknown model '<name>'; use a name returned by GET /v1/models The selector is misspelled or its provider is disabled. Call GET /v1/models.
The selected provider does not support this setting Laya, Von and Jev take no config keys. Remove config or send {}.
Value error, rendered CLM text exceeds the configured UTF-8 byte limit A CLM state plus instructions, or one criterion, is longer than DECIDEALOT_CLM_MAX_TEXT_BYTES. Shorten it or raise the limit.
List should have at most <n> items The batch is larger than DECIDEALOT_MAX_BATCH_REQUESTS.

MCP answers 421 or 403

421 means the request’s Host header is not in DECIDEALOT_MCP_ALLOWED_HOSTS; 403 means its browser Origin is not in DECIDEALOT_MCP_ALLOWED_ORIGINS. Both happen behind a proxy or tunnel that uses a public name. Add the exact name as shown in Expose MCP through a proxy, and keep the loopback defaults in the list.

401 UNAUTHORIZED

DECIDEALOT_API_KEY is set and the request has no Authorization: Bearer <key> header or a different key. MCP clients need the same header in their server configuration. /health never needs it.