deepseek-ai/deepseek-harness · error

session.selectModel failed: ${result.error.code}: ${result.e

Error message

session.selectModel failed: ${result.error.code}: ${result.error.message}

What it means

ModelDirectory.select() applies a chosen route via session.selectModel. On refusal it stores status:'error' with the code/message and throws 'session.selectModel failed: <code>: <message>'; a select superseded by a newer generation or a disposed directory throws only the raw code/message. The host validates routes before accepting, so a selection that landed is by construction servable.

Source

Thrown at packages/client/ui-model-selection/src/client/directory.ts:112

  async select(selection: ModelSelection): Promise<void> {
    this.assertAvailable()
    const generation = ++this.generation
    this.store.update((s) => { s.status = 'selecting'; s.error = null })
    const { result } = await this.sessions.selectModel({
      sessionId: this.sessionId,
      provider: selection.provider,
      model: selection.model,
      ...selection.reasoningEffort === undefined
        ? {}
        : { reasoningEffort: selection.reasoningEffort },
    })
    if (this.disposed || generation !== this.generation) {
      if (!result.ok) throw new Error(`${result.error.code}: ${result.error.message}`)
      return
    }
    if (!result.ok) {
      this.store.update((s) => { s.status = 'error'; s.error = `${result.error.code}: ${result.error.message}` })
      throw new Error(`session.selectModel failed: ${result.error.code}: ${result.error.message}`)
    }
    // The Host validated the route before accepting it, so a selection that
    // landed is by construction one it can serve.
    this.store.update((s) => {
      s.current = result.value.selected
      s.routable = true
      s.status = 'ready'
      s.error = null
    })
  }

  /**
   * Drop the previous Host generation's projection and repull it. Clearing
   * first prevents an unconsumed process-local selection from being displayed
   * while the restarted Host has restored the last logged model selection.
   */
  resetConnected(): void {
    if (this.disposed) return

View on GitHub (pinned to b150a551b8)

Solutions

  1. Reload the catalog (load/refresh) and pick from the fresh groups — the old option may no longer exist
  2. Check store status/error for the host's refusal code
  3. Retry once the provider is reachable
Defensive patterns

Strategy: try-catch

Validate before calling

const snap = directory.store.getSnapshot()
if (!snap.routable || snap.status === 'error') {
  await directory.load() // options are stale; make the user re-pick
  return
}

Try / catch

try {
  await directory.select(selection)
} catch {
  await directory.load() // options may be stale; re-pick from fresh groups
  throw new UserRetryError('re-pick a model from the refreshed list')
}

Prevention

When it happens

Trigger: Choosing a model (via apply, choose, or chooseEffort) when the host rejects the route: the model stopped being routable since the last catalog load, the provider is down, or the session is gone.

Common situations: Stale picker options after the provider changed its catalog mid-session; selecting during a provider outage.

Related errors


AI-assisted analysis of deepseek-ai/deepseek-harness@b150a551b8 (2026-08-24). Data as JSON: /api/errors/b6a619b86859d827. Report an issue: GitHub.