{"record":{"id":"40e39c8d7238c45a","repo":"wavetermdev/waveterm","slug":"terminal-input-request-failed-response-status","errorCode":null,"errorMessage":"terminal input request failed: ${response.status} ${response.statusText}","messagePattern":"terminal input request failed: (.+?) (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tsunami/frontend/src/vdom.tsx","lineNumber":310,"sourceCode":"}\n\nfunction WaveMarkdown({ elem, model }: { elem: VDomElem; model: TsunamiModel }) {\n    const props = useVDom(model, elem);\n    return (\n        <Markdown text={props?.text} style={props?.style} className={props?.className} scrollable={props?.scrollable} />\n    );\n}\n\nasync function sendTermInputEvent(event: VDomEvent) {\n    const response = await fetch(\"/api/terminput\", {\n        method: \"POST\",\n        headers: {\n            \"Content-Type\": \"application/json\",\n        },\n        body: JSON.stringify(event),\n    });\n    if (!response.ok) {\n        throw new Error(`terminal input request failed: ${response.status} ${response.statusText}`);\n    }\n}\n\nfunction WaveTerm({ elem, model }: { elem: VDomElem; model: TsunamiModel }) {\n    const props = useVDom(model, elem);\n    const hasOnData = props.onData != null;\n    const onData = React.useCallback(\n        (data: string | null, termsize: VDomTermSize | null) => {\n            const terminput: VDomTermInputData = {};\n            if (data != null) {\n                terminput.data = data;\n            }\n            if (termsize != null) {\n                terminput.termsize = termsize;\n            }\n            const event: VDomEvent = {\n                waveid: elem.waveid,\n                eventtype: \"onData\",","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/tsunami/frontend/src/vdom.tsx#L292-L328","documentation":"sendTermInputEvent POSTs terminal keystroke/input events to the Tsunami server as JSON. If the response is not ok, the error reports the HTTP status so the caller knows the terminal input never reached the backend.","triggerScenarios":"POST of a term-input event returns non-2xx: server down/restarting while the terminal UI is still accepting keys, endpoint changed, oversized or malformed event body (400), or proxy dropping the request.","commonSituations":"Typing into a WaveTerm vdom block after the Tsunami backend crashed or during a restart, port/baseUrl misconfiguration, firewall or proxy interference with the local server.","solutions":["Check status: ECONNREFUSED/502 → server down, restart Tsunami; 400 → inspect the serialized event body; 404 → endpoint path drift.","Verify the server URL/port used by vdom.tsx matches the running server.","Add retry/queueing for input events so transient failures don't drop keystrokes; surface connection state in the UI.","Confirm network/proxy allows the request to the local backend."],"exampleFix":"// before\nconst response = await fetch(url, { method: \"POST\", body: JSON.stringify(event) });\nif (!response.ok) throw new Error(`terminal input request failed: ${response.status} ${response.statusText}`);\n// after\nconst response = await fetch(url, { method: \"POST\", body: JSON.stringify(event) });\nif (!response.ok) {\n  if (response.status >= 500) inputQueue.push(event); // retry later\n  throw new Error(`terminal input request failed: ${response.status} ${response.statusText}`);\n}","handlingStrategy":"retry","validationCode":"async function serverReachable(url: string): Promise<boolean> {\n  try {\n    const res = await fetch(url, { method: \"OPTIONS\" });\n    return res.status < 500;\n  } catch {\n    return false;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await sendTermInputEvent(event);\n} catch (e) {\n  if (String(e.message).startsWith(\"terminal input request failed\")) {\n    console.warn(\"dropping/requeueing input, backend unreachable:\", e.message);\n    inputQueue.push(event); // or show disconnected indicator\n    return;\n  }\n  throw e;\n}","preventionTips":["Detect backend restarts and queue input events until connectivity returns.","Show a connection indicator on terminal blocks so users know when input can't be delivered.","Keep the server URL/port in one shared config to avoid drift.","Retry idempotent input events on 5xx with a small bounded queue."],"tags":["network","http","fetch","tsunami","terminal-input"],"backgroundTag":"http-request-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}