Fix DeepSeek Harness Model Errors: API Key & Custom Gateway

TroubleshootingPublished 2026-08-25Author: DSH Plugin Hub
DeepSeek HarnessDSH pluginmodel errorsAPI keycustom gateway
Fix DeepSeek Harness model errors by the error keyword: MISSING_CREDENTIAL/401 → API key, UNKNOWN_MODEL → model config, image rejection → input/compat.

When a DeepSeek Harness model errors, read the error keyword before doing anything: MISSING_CREDENTIAL and 401 point to the API key, UNKNOWN_MODEL points to model config, and image rejection or gateway failure points to input and compat in settings.yaml. Match the keyword in the quick table below, then follow the corresponding item.

Overview: read the error keyword first

Match the error keyword to its root cause before touching anything — different keywords mean completely different problems. The table below lists every error from the official troubleshooting section (source):

Error keywordMost likely causeJump to
MISSING_CREDENTIALAPI key not saved, or env var not injectedMISSING_CREDENTIAL
Fetch available models 401Wrong key, or the service has no GET /models endpointFetch 401
UNKNOWN_MODELModel is not among the configured providersUNKNOWN_MODEL
Image rejected before sendingModel has not declared image modality (input)Image rejected
Provider rejects image requestDeclared an image capability the endpoint does not provideImage request rejected
Custom gateway fails / reasoning content wrongReasoning format mis-guessed from the URL (compat)Reasoning format

Each error below is an item with error / cause / fix. DSH is still in developer preview and config fields follow the official docs; model config changes take effect on the next request without a restart (source).

Class 1: API key errors (MISSING_CREDENTIAL, 401)

MISSING_CREDENTIAL

  • Error: connection fails with MISSING_CREDENTIAL.
  • Cause: the key is not in place — either it was not saved on the model page, or the environment variable was not injected. The key itself never lives in settings.yaml.
  • Fix:
    1. Open Settings → Models, enter the API key on the provider card and save. The key is stored in $DSH_HOME/.credentials.yaml and the page only receives a masked descriptor, never the plaintext key (source).
    2. Or reference an environment variable name with apiKeyEnv in settings.yaml (not the key itself):
    yaml
    llm-pi-ai:
      providers:
        my-gateway:
          apiKeyEnv: GATEWAY_API_KEY   # the env var name, not the key
          api: openai-completions
          baseURL: https://gateway.example/v1
          models:
            - id: my-model
    
    1. Export the variable before starting: export GATEWAY_API_KEY="sk-...", then run DSH. Changes take effect on the next request — no restart (source).

Fetch available models returns 401

  • Error: Settings → Models → Fetch available models returns 401.
  • Cause: model discovery calls the OpenAI-compatible GET /models endpoint, which many gateways do not expose (source).
  • Fix:
    1. Confirm the key itself is correct.
    2. If the service has no GET /models endpoint, enter model ids manually in models — the ids must match the provider's actual model field exactly.

Class 2: Model config errors (UNKNOWN_MODEL)

UNKNOWN_MODEL

  • Error: requests fail with UNKNOWN_MODEL, or the model selector shows Select model and blocks input.
  • Cause: the requested model is not among the configured providers (source). Two typical cases:
    1. a saved session default points to a deleted provider;
    2. the custom provider's models list lacks this model id.
  • Fix:
    1. Case 1: re-select an already configured model, or re-add the deleted provider under the same id.
    2. Case 2: open $DSH_HOME/settings.yaml and append the id to that provider's models block:
    yaml
    models:
      - id: my-model
      - id: my-model-2   # append this line
    
    1. If you suspect the config was not written, run dsh --dump-config and check the model rows in the merged config tree before rebuilding the provider.

Provider IDs are permanent: requests, saved sessions, model defaults, and credential references all use them, so renaming one breaks every reference; the official way to rename is to add a new provider and delete the old one (source).

Class 3: Custom gateway compatibility errors (image modality, compat reasoning format)

This is the most confusing bucket: the key and Base URL are correct, yet the gateway rejects every request. The root cause is almost always config that does not declare what the model supports — undeclared models are treated as text-only (source).

Image rejected before sending

  • Error: attaching an image is rejected outright, naming the model as not supporting images.
  • Cause: manually entered models default to text-only — nothing can interrogate the endpoint for its modalities (source).
  • Fix: declare image modality for the model in settings.yaml:
    yaml
    llm-pi-ai:
      providers:
        my-gateway:
          apiKeyEnv: GATEWAY_API_KEY
          api: openai-completions
          baseURL: https://gateway.example/v1
          models:
            - id: vision-model
              input: [text, image]   # declare image support
    
    If every model on a route accepts images, set defaultInput: [text, image] once at the route as a fallback (the default is [text]); unknown modalities written anywhere are rejected (source).
  • Note: DeepSeek's own chat-completions route is text-only, and declaring input does not make it accept images — the provider rejects the request (source).

Provider rejects the image request

  • Error: the provider rejects the request, saying images are not supported by the endpoint.
  • Cause: you declared an image capability the endpoint does not actually provide — either in the model's input or the route's defaultInput.
  • Fix:
    1. Remove image from the list that granted it.
    2. Start a new session: attached images stay in the session log, so an old session keeps repeating the same request until it leaves (source).

Private gateway reasoning format (compat)

  • Error: key and baseURL are correct, but the custom gateway call fails, reasoning content is missing, or the model does not think the way it should.
  • Cause: pi-ai guesses the reasoning dialect from the endpoint URL (reasoning_effort, DeepSeek's thinking, z.ai's thinking object, etc.), and a private gateway's URL says nothing, so it is spoken to in the OpenAI dialect by default (source).
  • Fix: declare compat on the route or the model (effective only on the openai-completions protocol; the model level overrides the route level):
    yaml
    compat:
      thinkingFormat: deepseek   # tell the adapter this is a DeepSeek reasoning dialect
    
    Only compat.thinkingFormat and compat.supportsReasoningEffort are configurable. Other compat fields (such as maxTokensField and supportsStore) stay auto-detected and are deliberately not configurable — do not hard-code them.

General debugging flow

Run any model error through this order — most issues are found in the first three steps.

  1. Read the error keyword → match it in the quick table to locate the root-cause type.
  2. Check the declared config → is the key saved/injected, is the model id in the models list, are image modality and reasoning format declared?
  3. Confirm the version and docs → DSH is in developer preview; follow the official docs for field names.
  4. Use plugins as an aid → to see at a glance whether each call really goes through, pick model-related DSH plugins (token usage, cost tracking) from the model category in DSH Plugin Hub.

Notes

  1. Model config changes in settings.yaml take effect on the next request — no restart.
  2. apiKeyEnv takes an environment variable name, not the key itself; prefer saving keys in Settings → Models.
  3. Manually entered model ids must match the provider's model field exactly, or you get UNKNOWN_MODEL.
  4. Declare image modality with input, but never declare a modality the endpoint does not provide.
  5. DeepSeek's official chat-completions route is text-only; declaring images does not make it accept them.
  6. Let the error keyword steer you: MISSING_CREDENTIAL/401 → key, UNKNOWN_MODEL → model config, image rejection/request failure → input and compat.

Source: Configure models (official docs), dsh-llm-pi-ai README

FAQ

DeepSeek Harness says MISSING_CREDENTIAL. How do I fix it?

The key is not in place: save the API key for that provider in Settings → Models (stored in $DSH_HOME/.credentials.yaml), or reference an environment variable name with apiKeyEnv in settings.yaml and export it before starting.

My custom provider returns UNKNOWN_MODEL. What now?

The requested model is not among the configured providers: pick an already configured model, or append the missing model id to that provider's models block in settings.yaml. Provider IDs are permanent — rename by adding a new provider and deleting the old one, or old session references break.

DSH rejects an image before sending it. Why?

Manually entered models are treated as text-only until declared. Add input: [text, image] to the model, or set defaultInput: [text, image] at the route as a fallback. DeepSeek's own chat-completions route is text-only and cannot be changed via config.

Fetch available models returns 401. Is my API key wrong?

Not necessarily. Model discovery calls the OpenAI-compatible GET /models endpoint, and a service that does not expose it returns 401. Check the key first; if the endpoint is missing, enter model ids manually in the models block.

Custom gateway rejects requests but the key is correct. What else should I check?

Check the declared config: whether the model declares image modality (input) and whether the gateway's reasoning format is mis-guessed from the URL (compat.thinkingFormat). Changes take effect on the next request — no restart.

Sources