{"record":{"id":"69c7279f107f6372","repo":"Hmbown/CodeWhale","slug":"the-model-request-was-superseded","errorCode":null,"errorMessage":"The model request was superseded.","messagePattern":"The model request was superseded\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"info","filePath":"crates/tui/src/runtime_web/app.mjs","lineNumber":1934,"sourceCode":"    }\n\n    const modelDefault = String(preferredModel || provider.default_model || \"\").trim();\n    if (!provider.has_model_catalog) {\n      dom.newThreadModelInput.value = modelDefault;\n      app.newThreadLoading = false;\n      setNewThreadStatus(\"\");\n      syncNewThreadControls();\n      return;\n    }\n\n    app.newThreadLoading = true;\n    setNewThreadStatus(\"Loading models…\");\n    syncNewThreadControls();\n    try {\n      const modelEntries = await collectProviderModelPages(provider.id, async (path) => {\n        const page = await api(path);\n        if (generation !== app.newThreadGeneration || !dom.newThreadDialog.open) {\n          throw new Error(\"The model request was superseded.\");\n        }\n        return page;\n      });\n      if (generation !== app.newThreadGeneration || !dom.newThreadDialog.open) return;\n      const seen = new Set();\n      const models = [];\n      for (const entry of modelEntries) {\n        const id = String(entry?.id || \"\").trim();\n        const key = id.toLowerCase();\n        if (!id || seen.has(key)) continue;\n        seen.add(key);\n        models.push({\n          id,\n          image_input: [\"supported\", \"unsupported\", \"unknown\"].includes(entry?.image_input)\n            ? entry.image_input\n            : \"unknown\",\n        });\n      }","sourceCodeStart":1916,"sourceCodeEnd":1952,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_web/app.mjs#L1916-L1952","documentation":"Thrown by the fetch callback passed to collectProviderModelPages when the new-thread dialog's request generation advanced or the dialog closed while model pages were still being loaded. It is a deliberate cancellation signal, not a fault: stale pagination work must stop instead of populating a dialog the user already left or re-opened.","triggerScenarios":"The user closes the new-thread dialog or re-opens it (bumping app.newThreadGeneration) while a provider's model pages are mid-load; the in-flight api(path) then throws this error.","commonSituations":"User clicks away/cancels while models are loading; rapid open/close/open of the dialog; switching providers quickly, invalidating the previous provider's in-flight page fetches.","solutions":["Nothing to fix — the error is expected cancellation; ensure the caller treats it as benign","If it surfaces as a visible error toast, catch it and return silently instead of reporting","Avoid rapid re-opening of the dialog in automation/scripts while a load is pending","Check that dialog close handlers do not trigger redundant generation bumps that cancel loads"],"exampleFix":"// before: every thrown error becomes a toast\ntry { await loadModels(provider); } catch (e) { showToast(e.message); }\n// after: suppress expected cancellations\ntry { await loadModels(provider); }\ncatch (e) {\n  if (e.message !== 'The model request was superseded.') showToast(e.message);\n}","handlingStrategy":"try-catch","validationCode":"if (generation !== app.newThreadGeneration || !dom.newThreadDialog.open) return; // bail before fetching","typeGuard":null,"tryCatchPattern":"try { await loadModels(provider); } catch (e) { if (e.message === 'The model request was superseded.') return; throw e; }","preventionTips":["Treat superseded loads as silent cancellations","Debounce dialog open/close to avoid redundant generation bumps","Track a generation counter for every cancellable UI request","Never render results fetched under an older generation"],"tags":["cancellation","race-condition","ui"],"backgroundTag":"invalid-state-transition","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}