{"record":{"id":"9893cb8fbc804962","repo":"louislam/dockge","slug":"terminal-name-must-be-a-string","errorCode":null,"errorMessage":"Terminal name must be a string.","messagePattern":"Terminal name must be a string\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"backend/agent-socket-handlers/terminal-socket-handler.ts","lineNumber":17,"sourceCode":"import { DockgeServer } from \"../dockge-server\";\nimport { callbackError, callbackResult, checkLogin, DockgeSocket, ValidationError } from \"../util-server\";\nimport { log } from \"../log\";\nimport { InteractiveTerminal, MainTerminal, Terminal } from \"../terminal\";\nimport { Stack } from \"../stack\";\nimport { AgentSocketHandler } from \"../agent-socket-handler\";\nimport { AgentSocket } from \"../../common/agent-socket\";\n\nexport class TerminalSocketHandler extends AgentSocketHandler {\n    create(socket : DockgeSocket, server : DockgeServer, agentSocket : AgentSocket) {\n\n        agentSocket.on(\"terminalInput\", async (terminalName : unknown, cmd : unknown, callback) => {\n            try {\n                checkLogin(socket);\n\n                if (typeof(terminalName) !== \"string\") {\n                    throw new Error(\"Terminal name must be a string.\");\n                }\n\n                if (typeof(cmd) !== \"string\") {\n                    throw new Error(\"Command must be a string.\");\n                }\n\n                let terminal = Terminal.getTerminal(terminalName);\n                if (terminal instanceof InteractiveTerminal) {\n                    //log.debug(\"terminalInput\", \"Terminal found, writing to terminal.\");\n                    terminal.write(cmd);\n                } else {\n                    throw new Error(\"Terminal not found or it is not a Interactive Terminal.\");\n                }\n            } catch (e) {\n                callbackError(e, callback);\n            }\n        });\n","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/louislam/dockge/blob/f809ae192b571944ad773e9866d3e67064ae8043/backend/agent-socket-handlers/terminal-socket-handler.ts#L1-L35","documentation":"Thrown by the 'terminalInput' handler in TerminalSocketHandler when the terminalName argument is not a string. Terminal names are used to look up the active terminal map, so the handler validates the type first (then validates that cmd is a string too).","triggerScenarios":"socket.emit('terminalInput', terminalName, cmd) with terminalName undefined (terminal not attached yet), null, or an object (terminal instance passed instead of its name).","commonSituations":"Terminal component emits input before the connection/handshake assigns the terminal name; passing the xterm.js Terminal object instead of its registered name; automated input scripts with unset variables.","solutions":["Pass the registered terminal name string (e.g. the combined terminal name) exactly as attached","Only emit input after the terminal is attached and its name is known","Validate typeof terminalName === 'string' before emitting","If you hold a terminal object, send its name property, not the object"],"exampleFix":"// before\nsocket.emit(\"terminalInput\", terminal, cmd, cb); // object\n// after\nsocket.emit(\"terminalInput\", terminalName, cmd, cb); // string name","handlingStrategy":"type-guard","validationCode":"function assertTerminalInput(terminalName: unknown, cmd: unknown): asserts terminalName is string {\n  if (typeof terminalName !== \"string\") throw new TypeError(\"terminalName must be a string\");\n  if (typeof cmd !== \"string\") throw new TypeError(\"cmd must be a string\");\n}","typeGuard":"const isTerminalName = (v: unknown): v is string => typeof v === \"string\" && v.length > 0;","tryCatchPattern":"socket.emit(\"terminalInput\", terminalName, cmd, (res) => {\n  if (res && res.ok === false) console.warn(\"terminalInput rejected:\", res.msg);\n});","preventionTips":["Emit input only after the terminal is attached and its name is registered","Send the terminal's name string, not the xterm.js Terminal object","Guard the keydown/data handler with a terminalName typeof check"],"tags":["validation","socket-io","terminal","type-error"],"backgroundTag":"invalid-argument-type","analyzedSha":"f809ae192b571944ad773e9866d3e67064ae8043","analyzedAt":"2026-08-31T19:13:50.919Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}