{"record":{"id":"53b0012c78a70a10","repo":"deepseek-ai/deepseek-harness","slug":"session-models-failed-result-error-code-res","errorCode":null,"errorMessage":"session.models failed: ${result.error.code}: ${result.error.message}","messagePattern":"session\\.models failed: (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/client/ui-model-selection/src/client/directory.ts","lineNumber":74,"sourceCode":"  ) {}\n\n  /**\n   * Refresh the advisory directory (both entries call this on open).\n   * Failure preserves the last good groups and current selection.\n   * @returns the fresh directory value.\n   */\n  async load(): Promise<SessionModels> {\n    this.assertAvailable()\n    const generation = ++this.generation\n    this.store.update((s) => { s.status = 'loading'; s.error = null })\n    const { result } = await this.sessions.models({ sessionId: this.sessionId })\n    if (this.disposed || generation !== this.generation) {\n      if (!result.ok) throw new Error(`${result.error.code}: ${result.error.message}`)\n      return result.value\n    }\n    if (!result.ok) {\n      this.store.update((s) => { s.status = 'error'; s.error = `${result.error.code}: ${result.error.message}` })\n      throw new Error(`session.models failed: ${result.error.code}: ${result.error.message}`)\n    }\n    const { current, routable, groups, failures } = result.value\n    this.store.update((s) => {\n      s.current = current\n      s.routable = routable\n      s.groups = groups\n      s.failures = failures\n      s.status = 'ready'\n      s.error = null\n    })\n    return result.value\n  }\n\n  /**\n   * Select the complete provider/model/reasoning selection (both entries submit through here). Success\n   * updates the shared current; failure surfaces on the store and throws so\n   * each entry's own retry surface engages.\n   * @param selection - provider, provider-owned model id, and optional adapter-owned effort.","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/client/ui-model-selection/src/client/directory.ts#L56-L92","documentation":"ModelDirectory.load() fetches the routable model catalog via session.models. On failure it records status:'error' plus the code/message in its store and then throws 'session.models failed: <code>: <message>'. If the directory was disposed or a newer generation superseded this load, the store is left untouched and only the raw code/message throws.","triggerScenarios":"Opening or refreshing the model picker while the models RPC fails: provider catalog unreachable from the host, authorization failure, or the session dead. load() runs from resetConnected, apply, refresh, reload, and ModelSelect mount.","commonSituations":"Provider outage at host startup; expired provider credentials; opening the picker right after a reconnect before the session resynced.","solutions":["Retry the load once the provider is reachable — the store keeps the error text for the retry UI","Read store status/error to surface the host-side refusal code to the user","Confirm the session binding is live before reloading"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const snap = directory.store.getSnapshot()\nif (snap.status === 'error' || snap.groups.length === 0) await directory.load()","typeGuard":null,"tryCatchPattern":"try {\n  await directory.load()\n} catch {\n  renderModelErrorWithRetry(directory.store.getSnapshot().error) // status stays 'error' for the UI\n}","preventionTips":["Read the store status and error for UI state instead of re-throwing into components","Retry catalog loads only after the provider or connection recovers"],"tags":["rpc","models","provider","catalog"],"backgroundTag":"rpc-request-failed","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}