louislam/dockge · error · ValidationError

isAdd must be a boolean

Error message

isAdd must be a boolean

What it means

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.

Source

Thrown at backend/agent-socket-handlers/docker-socket-handler.ts:348

            } catch (e) {
                callbackError(e, callback);
            }
        });
    }

    async saveStack(server : DockgeServer, name : unknown, composeYAML : unknown, composeENV : unknown, isAdd : unknown) : Promise<Stack> {
        // Check types
        if (typeof(name) !== "string") {
            throw new ValidationError("Name must be a string");
        }
        if (typeof(composeYAML) !== "string") {
            throw new ValidationError("Compose YAML must be a string");
        }
        if (typeof(composeENV) !== "string") {
            throw new ValidationError("Compose ENV must be a string");
        }
        if (typeof(isAdd) !== "boolean") {
            throw new ValidationError("isAdd must be a boolean");
        }

        const stack = new Stack(server, name, composeYAML, composeENV, false);
        await stack.save(isAdd);
        return stack;
    }

}

View on GitHub (pinned to f809ae192b)

Solutions

  1. Pass a real boolean: true for create, false for update
  2. Convert form strings with isAdd === 'true' or Boolean(...) appropriately before emitting
  3. Include the flag explicitly in every emit of 'create'/'stack'
  4. Default it at the call site: const isAddFlag = isAdd === undefined ? false : isAdd

Example fix

// before
socket.emit("create", name, yaml, env, "true", cb); // string
// after
socket.emit("create", name, yaml, env, true, cb);
Defensive patterns

Strategy: type-guard

Validate before calling

function assertIsAdd(v: unknown): asserts v is boolean {
  if (typeof v !== "boolean") throw new TypeError("isAdd must be a boolean (true=create, false=update)");
}

Type guard

const isBoolean = (v: unknown): v is boolean => typeof v === "boolean";

Try / catch

try {
  assertIsAdd(isAdd);
  socket.emit("create", name, yaml, env, isAdd, cb);
} catch (e) { showError((e as Error).message); }

Prevention

When it happens

Trigger: 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.

Common situations: Adding a new saveStack call site and forgetting the fourth argument; HTML form values arriving as strings; refactors dropping the flag from the payload.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


AI-assisted analysis of louislam/dockge@f809ae192b (2026-08-31). Data as JSON: /api/errors/c85d469a09ee88b7. Report an issue: GitHub.