{"record":{"id":"857a7156d6d70976","repo":"odysseus-dev/odysseus","slug":"data-error-http-data-status-500","errorCode":null,"errorMessage":"data.error || ('HTTP ' + (data.status || 500))","messagePattern":"data\\.error \\|\\| \\('HTTP ' \\+ \\(data\\.status \\|\\| 500\\)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"static/js/chat.js","lineNumber":6441,"sourceCode":"      let newText = '';\n\n      while (true) {\n        const { done, value } = await reader.read();\n        if (done) break;\n        buffer += decoder.decode(value, { stream: true });\n        const lines = buffer.split('\\n');\n        buffer = lines.pop() || '';\n\n        for (const line of lines) {\n          if (!line.startsWith('data: ')) continue;\n          const payload = line.slice(6).trim();\n          if (payload === '[DONE]') continue;\n          try {\n            const data = JSON.parse(payload);\n            // The endpoint streams `event: error\\ndata: {error,status}` on\n            // failure — surface it instead of silently hanging on \"Rewriting…\".\n            if (data.error) {\n              throw new Error(data.error || ('HTTP ' + (data.status || 500)));\n            }\n            // Reasoning tokens (vLLM --reasoning-parser: Qwen3 / DeepSeek-R1)\n            // arrive as separate {delta, thinking:true} chunks. They are NOT\n            // the rewrite — fold them away so they don't pollute the result.\n            if (data.thinking) continue;\n            if (data.delta) {\n              newText += data.delta;\n              _killRwSpin();\n              if (bodyEl) {\n                bodyEl.innerHTML = markdownModule.processWithThinking(\n                  markdownModule.squashOutsideCode(newText)\n                );\n              }\n            }\n          } catch (e) {\n            if (e instanceof Error && e.message) throw e;  // re-throw real errors\n            /* ignore JSON parse noise */\n          }","sourceCodeStart":6423,"sourceCodeEnd":6459,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/chat.js#L6423-L6459","documentation":"HTTP 400 from POST /webhooks when the `name` form field, after strip() and truncation to MAX_NAME_LEN (100), is empty — i.e. missing, only whitespace, or a name composed solely of characters cut off by the 100-char truncation edge case. This is the first validation on webhook creation, before URL and events checks.","triggerScenarios":"POST /webhooks (multipart/form or urlencoded) with name omitted, name=\"   \", or name=\"\" — for example a curl call using -d that drops an empty field, or a UI form submitted before the name input was filled.","commonSituations":"Form field named differently than expected (e.g. 'label' instead of 'name') so FastAPI binds the default ''; client sends JSON body while the route expects Form fields; automated scripts creating webhooks from a config where one entry lacks a name.","solutions":["Include a non-empty `name` form field (1–100 chars) in the request.","Ensure the field is sent as form data, not JSON — the parameters are Form('') so a JSON body yields defaults.","Trim the name client-side and reject empty before submitting.","Check for stray field-name typos (name vs title/label) in the client."],"exampleFix":"# before\ncurl -X POST url/api/webhooks -H 'Content-Type: application/json' -d '{\"url\": \"https://x.example/hook\"}'\n\n# after\ncurl -X POST url/api/webhooks -F 'name=deploy hook' -F 'url=https://x.example/hook' -F 'events=message.created'","handlingStrategy":"validation","validationCode":"const name = (rawName ?? '').trim();\nif (!name) return alert('Webhook name is required');\nconst fd = new FormData();\nfd.set('name', name); // plus url, events, secret\nawait fetch('/api/webhooks', { method: 'POST', body: fd });","typeGuard":"function isCreatableWebhook(f: { name?: unknown }): boolean {\n  return typeof f.name === 'string' && f.name.trim().length > 0 && f.name.trim().length <= 100;\n}","tryCatchPattern":"const r = await fetch('/api/webhooks', { method: 'POST', body: fd });\nif (r.status === 400) showFormError(await r.text()); // message names the failing field","preventionTips":["Send form fields (multipart/urlencoded), not JSON — the route binds Form parameters","Require a non-empty trimmed name in the UI before submit","Keep names within 100 characters (MAX_NAME_LEN)"],"tags":["webhook","http-400","form-validation","admin"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}