{"record":{"id":"b1b1f0ad389408e0","repo":"louislam/dockge","slug":"name-must-be-a-string","errorCode":null,"errorMessage":"Name must be a string","messagePattern":"Name must be a string","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"info","filePath":"backend/agent-socket-handlers/docker-socket-handler.ts","lineNumber":47,"sourceCode":"            try {\n                checkLogin(socket);\n                await this.saveStack(server, name, composeYAML, composeENV, isAdd);\n                callbackResult({\n                    ok: true,\n                    msg: \"Saved\",\n                    msgi18n: true,\n                }, callback);\n                server.sendStackList();\n            } catch (e) {\n                callbackError(e, callback);\n            }\n        });\n\n        agentSocket.on(\"deleteStack\", async (name : unknown, callback) => {\n            try {\n                checkLogin(socket);\n                if (typeof(name) !== \"string\") {\n                    throw new ValidationError(\"Name must be a string\");\n                }\n                const stack = await Stack.getStack(server, name);\n\n                try {\n                    await stack.delete(socket);\n                } catch (e) {\n                    server.sendStackList();\n                    throw e;\n                }\n\n                server.sendStackList();\n                callbackResult({\n                    ok: true,\n                    msg: \"Deleted\",\n                    msgi18n: true,\n                }, callback);\n\n            } catch (e) {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/louislam/dockge/blob/f809ae192b571944ad773e9866d3e67064ae8043/backend/agent-socket-handlers/docker-socket-handler.ts#L29-L65","documentation":"The deleteStack agent socket handler validates that the first argument is a string before using it as a stack name; a non-string (number, object, undefined, null) throws ValidationError('Name must be a string'). This is an input validation guard against malformed socket events.","triggerScenarios":"A client emits agent event 'deleteStack' with a non-string first argument — e.g. deleteStack(undefined), a parsed JSON object, a numeric id, or a forgotten argument so name is undefined.","commonSituations":"Custom scripts or API clients passing a stack id instead of the stack name; omitting the argument when calling the socket event; serialization bugs where the name arrives as an object.","solutions":["Emit deleteStack with a plain string stack name, e.g. agentSocket.emit('deleteStack', 'my-stack', callback)","Check the caller is passing the name property, not an object containing it","Handle the callbackError response (ok:false, msg:'Name must be a string') in the client and fix the payload"],"exampleFix":"// before\nagentSocket.emit(\"deleteStack\", { name: \"my-stack\" }, cb);\n// after\nagentSocket.emit(\"deleteStack\", \"my-stack\", cb);","handlingStrategy":"type-guard","validationCode":"if (typeof name !== \"string\" || name.length === 0) {\n    throw new Error(\"deleteStack requires a non-empty string name\");\n}","typeGuard":"function isStackName(v: unknown): v is string {\n    return typeof v === \"string\" && v.length > 0;\n}","tryCatchPattern":"agentSocket.emit(\"deleteStack\", name, (res) => {\n    if (!res.ok && res.msg === \"Name must be a string\") {\n        // fix payload: name must be a plain string\n    }\n});","preventionTips":["Always pass a string stack name, never an object or id","Check arguments before emitting socket events","Handle callbackError ok:false responses in the client"],"tags":["validation","socket","typescript"],"backgroundTag":"invalid-argument-type","analyzedSha":"f809ae192b571944ad773e9866d3e67064ae8043","analyzedAt":"2026-08-31T19:13:50.919Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}