{"record":{"id":"fa81407308cdbe21","repo":"Hmbown/CodeWhale","slug":"the-runtime-returned-an-incomplete-provider-model-catalog","errorCode":null,"errorMessage":"The Runtime returned an incomplete provider model catalog.","messagePattern":"The Runtime returned an incomplete provider model catalog\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_web/app.mjs","lineNumber":691,"sourceCode":"      || response.total > MAX_PROVIDER_MODELS) {\n      throw new Error(\"The Runtime returned an invalid provider model page.\");\n    }\n    if (expectedTotal !== undefined && expectedTotal !== response.total) {\n      throw new Error(\"The provider catalog changed; restart loading its models.\");\n    }\n    expectedTotal = response.total;\n    const pageEntries = response.models;\n    if (entries.length + pageEntries.length > MAX_PROVIDER_MODELS) {\n      throw new Error(`The provider catalog exceeds ${MAX_PROVIDER_MODELS} models.`);\n    }\n    entries.push(...pageEntries);\n\n    const nextCursor = typeof response?.nextCursor === \"string\"\n      ? response.nextCursor.trim()\n      : \"\";\n    if (!nextCursor) {\n      if (entries.length !== expectedTotal) {\n        throw new Error(\"The Runtime returned an incomplete provider model catalog.\");\n      }\n      return entries;\n    }\n    if (pageEntries.length === 0 || seenCursors.has(nextCursor)) {\n      throw new Error(\"The Runtime returned a non-progressing model cursor.\");\n    }\n    if (entries.length >= expectedTotal) {\n      throw new Error(\"The Runtime returned a cursor beyond its provider model catalog.\");\n    }\n    seenCursors.add(nextCursor);\n    cursor = nextCursor;\n  }\n  throw new Error(`The provider catalog exceeds ${MAX_PROVIDER_MODELS} models.`);\n}\n\nfunction startBrowserClient() {\n  const dom = {\n    shell: document.querySelector(\"#app-shell\"),","sourceCodeStart":673,"sourceCodeEnd":709,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_web/app.mjs#L673-L709","documentation":"On the final page (empty nextCursor) the loader verifies that the number of accumulated entries equals the catalog's declared `total`. A mismatch means the Runtime ended pagination early or late relative to its own count, i.e. it returned a truncated or over-long catalog.","triggerScenarios":"The Runtime's models endpoint returns a terminal (empty) nextCursor while entries.length !== expectedTotal — e.g. it served fewer pages than `total` implies, or more entries than total.","commonSituations":"A Runtime bug in cursor generation that drops the last page; a provider catalog shrunk between the first page and the last; a proxy truncating a response body mid-pagination; partially failed provider sync.","solutions":["Reload the dialog / retry the load — a transient truncation will resolve","Restart the Runtime to rule out a stale or buggy backend build","Compare the provider's actual model count with the `total` field the Runtime returns","Check proxy/gateway logs for truncated responses on the models endpoint"],"exampleFix":"// before: trusting entries even when short\nreturn entries;\n// after: surface a clear error when the catalog is short\nif (nextCursor === '' && entries.length !== expectedTotal) {\n  throw new Error('incomplete provider model catalog: got ' + entries.length + ' of ' + expectedTotal);\n}","handlingStrategy":"retry","validationCode":"if (pageDone && entries.length !== expectedTotal) console.warn('catalog short:', entries.length, 'of', expectedTotal);","typeGuard":"const catalogComplete = (entries, total) => Array.isArray(entries) && entries.length === total;","tryCatchPattern":"try { models = await loadCatalog(); } catch (e) { if (String(e.message).includes('incomplete')) models = await loadCatalog(); }","preventionTips":["Retry truncated loads once before reporting","Verify provider sync completes before exposing the catalog","Check proxies do not truncate JSON bodies","Keep Runtime cursor logic and total computation in one place"],"tags":["pagination","data-integrity","provider-catalog"],"backgroundTag":"unexpected-response-shape","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"}