google-gemini/gemini-cli · critical · Error

Model policy chain must include at least one model.

Error message

Model policy chain must include at least one model.

What it means

Thrown by validateModelPolicyChain() when the chain array has length 0. The model policy chain is an ordered list of ModelPolicy entries that the availability subsystem walks to find a usable model; each entry defines a model ID, retry behavior, and whether it is a last-resort fallback. An empty chain means the system has no model to try at all, which would cause undefined behavior downstream.

Source

Thrown at packages/core/src/availability/policyCatalog.ts:154

}

export function getFlashLitePolicyChain(): ModelPolicyChain {
  return cloneChain(FLASH_LITE_CHAIN);
}

/**
 * Provides a default policy scaffold for models not present in the catalog.
 */
export function createDefaultPolicy(
  model: string,
  options?: { isLastResort?: boolean },
): ModelPolicy {
  return definePolicy({ model, isLastResort: options?.isLastResort });
}

export function validateModelPolicyChain(chain: ModelPolicyChain): void {
  if (chain.length === 0) {
    throw new Error('Model policy chain must include at least one model.');
  }
  const lastResortCount = chain.filter((policy) => policy.isLastResort).length;
  if (lastResortCount === 0) {
    throw new Error('Model policy chain must include an `isLastResort` model.');
  }
  if (lastResortCount > 1) {
    throw new Error('Model policy chain must only have one `isLastResort`.');
  }
}

/**
 * Helper to define a ModelPolicy with default actions and state transitions.
 * Ensures every policy is a fresh instance to avoid shared state.
 */
function definePolicy(config: PolicyConfig): ModelPolicy {
  return {
    model: config.model,
    isLastResort: config.isLastResort,

View on GitHub (pinned to 5024443c72)

Solutions

  1. Ensure the chain builder always returns at least one ModelPolicy entry; use createDefaultPolicy(model, { isLastResort: true }) as a guaranteed fallback.
  2. If filtering models, always append a last-resort policy after filtering so the chain is never empty.
  3. Add a guard after building: if (chain.length === 0) chain = [createSingleModelChain(DEFAULT_GEMINI_MODEL)].
  4. Validate configuration overrides that affect model selection to confirm they produce non-empty chains.

Example fix

// before — filter can produce empty array
const chain = catalog
  .filter((m) => m.available)
  .map((m) => createDefaultPolicy(m.id));
validateModelPolicyChain(chain); // throws if all unavailable

// after — guarantee a last-resort fallback
const chain = catalog
  .filter((m) => m.available)
  .map((m) => createDefaultPolicy(m.id));
if (chain.length === 0) {
  chain.push(createDefaultPolicy(DEFAULT_GEMINI_MODEL, { isLastResort: true }));
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure chain is never empty before validation
if (chain.length === 0) {
  chain = [createSingleModelChain(DEFAULT_GEMINI_MODEL)];
}
validateModelPolicyChain(chain);

Type guard

function isNonEmptyChain(chain: ModelPolicyChain): chain is [ModelPolicy, ...ModelPolicy[]] {
  return chain.length > 0;
}

Try / catch

try {
  validateModelPolicyChain(chain);
} catch (e) {
  if (e instanceof Error && e.message.includes('must include at least one model')) {
    // Fall back to a safe default chain
    chain = [createSingleModelChain(DEFAULT_GEMINI_MODEL)];
    validateModelPolicyChain(chain);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling validateModelPolicyChain([]) — passing an empty array. This typically happens when a chain builder function (e.g., createAutoRoutingChain or a custom one) returns [] due to a logic error, or when a configuration override empties the chain.

Common situations: A custom chain builder returns an empty array under an unhandled configuration branch; filtering a chain to remove all entries (e.g., filtering out unavailable models); a config migration or settings.json edit that accidentally sets an empty model list; programmatic chain construction that pushes into an array conditionally and all conditions are false.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/2b5a20373e7b1a16. Report an issue: GitHub.