Skip to content

undefined-model-reference

A Compose service references a model that isn't declared under the top-level models element. Why the names must match and how the binding works.

On this page

With Docker Model Runner, a service consumes a model in two steps: the top-level models: element declares it under a name and maps it to an OCI artifact, and the service's own models: section references that name, either as a plain list or as a map with endpoint_var/model_var bindings. The names must match exactly. A typo, or a model renamed in one place but not the other, leaves a reference with nothing to resolve to. This rule flags every service-level model reference that no top-level declaration satisfies.

What the rule catches

compose.yaml — service binds a model name that doesn't exist
services:
  agent:
    image: my-agent:1.2.0
    models:
      gemma:
        endpoint_var: MODEL_RUNNER_URL
models:
  gemma3:
    model: ai/gemma3:4B-Q4_0

Scanning this file reports:

✖ ERROR [docker-doctor/undefined-model-reference]
  Service 'agent' references model 'gemma', which is not declared in the top-level models section. Compose cannot resolve it.

Why it matters

This is a hard error caught cheap. The mismatch is invisible to a YAML syntax check, because both sections are individually valid. At runtime it appears as environment variables that were never injected, which reads like an app bug, not a compose bug. A linter comparing the two name sets finds it before anything is pulled or started, which is exactly the class of cross-reference mistake static analysis exists for.

How to fix it

Every name under a service's models: must match an entry in the top-level models: element. Declare the model there (with its model: OCI artifact) or fix the reference.

compose.yaml — reference and declaration agree
services:
  agent:
    image: my-agent:1.2.0
    models:
      gemma3:
        endpoint_var: MODEL_RUNNER_URL
models:
  gemma3:
    model: ai/gemma3:4B-Q4_0

The binding is how connection details reach your app: Compose starts the declared model via Model Runner and injects its URL and identifier into the service's environment, using either the default variables or the names you chose with endpoint_var/model_var. That's also why this error can surface confusingly late: the symptom is an agent failing to reach its endpoint at startup, several layers away from the one-word mismatch in the compose file. The rule intentionally has no opinion in the other direction; a declared model that no service references yet is fine.

Rule details

  • Rule keydocker-doctor/undefined-model-reference
  • Category — Compose
  • Default severityerror
  • Applies to — Docker Compose files

Explain this rule from the CLI:

npx @docker-doctor/cli@latest rules explain docker-doctor/undefined-model-reference

Change its severity — or turn it off — in your config file:

// docker-doctor.config.ts
export default {
  rules: {
    "docker-doctor/undefined-model-reference": "off",
  },
};

Severity affects the health score: error findings cost more points than warning, and info costs the least.