louislam/dockge · error · ValidationError

Stack name and service name must be strings

Error message

Stack name and service name must be strings

What it means

ValidationError thrown by the 'startService' handler when either stackName or serviceName is not a string. Both values are interpolated into Docker service commands (docker compose start <service> in stack <name>), so both are strictly type-checked before use.

Source

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

                const dockerStats = Object.fromEntries(await server.getDockerStats());
                callbackResult({
                    ok: true,
                    dockerStats,
                }, callback);
                server.sendStackList();
            } catch (e) {
                callbackError(e, callback);
            }
        });

        // Start a service
        agentSocket.on("startService", async (stackName: unknown, serviceName: unknown, callback) => {
            try {
                checkLogin(socket);

                if (typeof (stackName) !== "string" || typeof (serviceName) !== "string") {
                    throw new ValidationError("Stack name and service name must be strings");
                }

                const stack = await Stack.getStack(server, stackName);
                await stack.startService(socket, serviceName);
                stack.joinCombinedTerminal(socket); // Ensure the combined terminal is joined
                callbackResult({
                    ok: true,
                    msg: "Service " + serviceName + " started"
                }, callback);
                server.sendStackList();
            } catch (e) {
                callbackError(e, callback);
            }
        });

        // Stop a service
        agentSocket.on("stopService", async (stackName: unknown, serviceName: unknown, callback) => {
            try {

View on GitHub (pinned to f809ae192b)

Solutions

  1. Ensure both arguments are strings in the emit call and in the correct order (stackName, serviceName)
  2. Validate before emitting: if (typeof s === 'string' && typeof svc === 'string') socket.emit(...)
  3. Fix the component so serviceName is always defined for rendered rows
  4. Log the payload values when the error occurs to find which one is malformed

Example fix

// before
socket.emit("startService", stack, service?.name, cb);
// after
if (typeof service?.name === "string") socket.emit("startService", stack.name, service.name, cb);
Defensive patterns

Strategy: validation

Validate before calling

function assertStartServiceArgs(stackName: unknown, serviceName: unknown): asserts stackName is string {
  if (typeof stackName !== "string" || typeof serviceName !== "string") {
    throw new TypeError("startService requires string stackName and serviceName");
  }
}

Type guard

const bothStrings = (a: unknown, b: unknown): a is string => typeof a === "string" && typeof b === "string";

Try / catch

try {
  assertStartServiceArgs(stackName, serviceName);
  socket.emit("startService", stackName, serviceName, (res) => {
    if (!res.ok) console.error("startService failed:", res.msg);
  });
} catch (e) { console.error(e); }

Prevention

When it happens

Trigger: socket.emit('startService', stackName, serviceName) with either argument null/undefined/non-string — e.g. serviceName undefined because the service row was not hydrated, or stackName an object.

Common situations: Clicking start on a service whose name prop is missing; passing the wrong argument order (serviceName first); scripts iterating services with undefined entries.

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/5f7398c7fb3065a1. Report an issue: GitHub.