{"record":{"id":"c85d469a09ee88b7","repo":"louislam/dockge","slug":"isadd-must-be-a-boolean","errorCode":null,"errorMessage":"isAdd must be a boolean","messagePattern":"isAdd must be a boolean","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"backend/agent-socket-handlers/docker-socket-handler.ts","lineNumber":348,"sourceCode":"            } catch (e) {\n                callbackError(e, callback);\n            }\n        });\n    }\n\n    async saveStack(server : DockgeServer, name : unknown, composeYAML : unknown, composeENV : unknown, isAdd : unknown) : Promise<Stack> {\n        // Check types\n        if (typeof(name) !== \"string\") {\n            throw new ValidationError(\"Name must be a string\");\n        }\n        if (typeof(composeYAML) !== \"string\") {\n            throw new ValidationError(\"Compose YAML must be a string\");\n        }\n        if (typeof(composeENV) !== \"string\") {\n            throw new ValidationError(\"Compose ENV must be a string\");\n        }\n        if (typeof(isAdd) !== \"boolean\") {\n            throw new ValidationError(\"isAdd must be a boolean\");\n        }\n\n        const stack = new Stack(server, name, composeYAML, composeENV, false);\n        await stack.save(isAdd);\n        return stack;\n    }\n\n}\n\n","sourceCodeStart":330,"sourceCodeEnd":358,"githubUrl":"https://github.com/louislam/dockge/blob/f809ae192b571944ad773e9866d3e67064ae8043/backend/agent-socket-handlers/docker-socket-handler.ts#L330-L358","documentation":"ValidationError from saveStack: the isAdd argument must be a boolean — it selects whether stack.save() creates a new stack (true) or updates an existing one (false). Any other type (undefined, 0/1, 'true') is rejected before saving to disk.","triggerScenarios":"Emitting 'create'/'stack' with isAdd undefined (flag never set by the caller), the string \"true\"/\"false\" from a form, or 0/1 from a numeric toggle.","commonSituations":"Adding a new saveStack call site and forgetting the fourth argument; HTML form values arriving as strings; refactors dropping the flag from the payload.","solutions":["Pass a real boolean: true for create, false for update","Convert form strings with isAdd === 'true' or Boolean(...) appropriately before emitting","Include the flag explicitly in every emit of 'create'/'stack'","Default it at the call site: const isAddFlag = isAdd === undefined ? false : isAdd"],"exampleFix":"// before\nsocket.emit(\"create\", name, yaml, env, \"true\", cb); // string\n// after\nsocket.emit(\"create\", name, yaml, env, true, cb);","handlingStrategy":"type-guard","validationCode":"function assertIsAdd(v: unknown): asserts v is boolean {\n  if (typeof v !== \"boolean\") throw new TypeError(\"isAdd must be a boolean (true=create, false=update)\");\n}","typeGuard":"const isBoolean = (v: unknown): v is boolean => typeof v === \"boolean\";","tryCatchPattern":"try {\n  assertIsAdd(isAdd);\n  socket.emit(\"create\", name, yaml, env, isAdd, cb);\n} catch (e) { showError((e as Error).message); }","preventionTips":["Pass literals true/false, never \"true\"/\"false\" strings from forms","Convert form values with value === \"true\" before emitting","Define a typed payload interface for the create/stack events"],"tags":["validation","socket-io","typescript","type-error"],"backgroundTag":"invalid-argument-type","analyzedSha":"f809ae192b571944ad773e9866d3e67064ae8043","analyzedAt":"2026-08-31T19:13:50.919Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}