{"record":{"id":"2b5568c69740f62e","repo":"odysseus-dev/odysseus","slug":"http-res-status-body-body-slice-0-16","errorCode":null,"errorMessage":"HTTP ${res.status}${body ? ': ' + body.slice(0, 160) : ''}","messagePattern":"HTTP \\$\\{res\\.status\\}\\$\\{body \\? ': ' \\+ body\\.slice\\(0, 160\\) : ''\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"static/js/markdown.js","lineNumber":1046,"sourceCode":"\n    const parsed = new URL(baseUrl, window.location.origin);\n    const fd = new FormData();\n    fd.append('base_url', baseUrl);\n    fd.append('name', _endpointNameFromUrl(baseUrl));\n    fd.append('model_type', 'llm');\n    fd.append('endpoint_kind', 'auto');\n    fd.append('skip_probe', 'true');\n    if (/^(localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0)$/i.test(parsed.hostname)) {\n      fd.append('container_local', 'true');\n    }\n    const res = await fetch('/api/model-endpoints', {\n      method: 'POST',\n      credentials: 'same-origin',\n      body: fd,\n    });\n    if (!res.ok) {\n      const body = await res.text().catch(() => '');\n      throw new Error(`HTTP ${res.status}${body ? ': ' + body.slice(0, 160) : ''}`);\n    }\n    btn.classList.add('added');\n    btn.innerHTML = '<span aria-hidden=\"true\">✓</span><span>Added</span>';\n    window.dispatchEvent(new CustomEvent('ge:model-endpoints-updated', { detail: { baseUrl } }));\n    if (window.modelsModule?.refreshModels) await window.modelsModule.refreshModels(true);\n    if (window.sessionModule?.updateModelPicker) window.sessionModule.updateModelPicker();\n    uiModule.showToast?.(`Model endpoint added: ${_endpointNameFromUrl(baseUrl)}`);\n  } catch (err) {\n    btn.disabled = false;\n    btn.innerHTML = original;\n    uiModule.showError?.(`Add endpoint failed: ${err.message || err}`);\n  }\n}\n\n(function _watchModelEndpointLinks() {\n  if (window._modelEndpointLinkWatcherWired) return;\n  window._modelEndpointLinkWatcherWired = true;\n","sourceCodeStart":1028,"sourceCodeEnd":1064,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/markdown.js#L1028-L1064","documentation":"Thrown in markdown.js when adding a model endpoint via POST /api/model-endpoints fails. The first 160 chars of the response body are appended to the status. The button UI is restored and the error surfaced via showError in the catch, so the 'Add endpoint' affordance recovers cleanly.","triggerScenarios":"Submitting an endpoint URL that fails server-side validation (unreachable base URL even with skip_probe=true, malformed URL, duplicate endpoint); a provider value the backend rejects; container_local flag mismatch for localhost URLs.","commonSituations":"Adding an Ollama/LM Studio URL with wrong port or scheme; adding an endpoint that duplicates one already registered; pointing at a container-internal address without the container_local hint because the hostname regex did not match (e.g. host.docker.internal).","solutions":["Verify the URL opens in a browser/curl from the same machine, including port and /v1 suffix if required.","Read the truncated body text — FastAPI validation errors name the offending field.","Remove the existing duplicate endpoint first if the server rejects re-registration.","For Docker setups, use the container-reachable address (host.docker.internal or service name)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let parsed; try { parsed = new URL(baseUrl); } catch { showError('Invalid URL'); return; }\nif (!/^https?:$/.test(parsed.protocol)) { showError('Use http(s) URL'); return; }","typeGuard":"const isEndpointPayload = (fd) => fd instanceof FormData && fd.get('base_url');","tryCatchPattern":"try { ... } catch (err) { btn.disabled = false; btn.innerHTML = original; uiModule.showError(`Add endpoint failed: ${err.message}`); }","preventionTips":["Validate URL shape client-side before POSTing","Show the truncated body — it names the failing field","Disable the button during flight and always restore it in catch"],"tags":["llm-endpoints","http","validation","configuration"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}