louislam/dockge · error · ValidationError
dockerRunCommand must be a string
Error message
dockerRunCommand must be a string
What it means
The 'composerize' socket event converts a docker run command into docker-compose YAML. The dockerRunCommand argument is typed unknown, so the handler first performs a strict typeof check and throws a ValidationError if it is not a string. This guarantees composerize() only ever receives string input.
Source
Thrown at backend/socket-handlers/main-socket-handler.ts:329
// Disconnect all other socket clients of the user
socket.on("disconnectOtherSocketClients", async () => {
try {
checkLogin(socket);
server.disconnectAllSocketClients(socket.userID, socket.id);
} catch (e) {
if (e instanceof Error) {
log.warn("disconnectOtherSocketClients", e.message);
}
}
});
// composerize
socket.on("composerize", async (dockerRunCommand : unknown, callback) => {
try {
checkLogin(socket);
if (typeof(dockerRunCommand) !== "string") {
throw new ValidationError("dockerRunCommand must be a string");
}
// Option: 'latest' | 'v2x' | 'v3x'
let composeTemplate = composerize(dockerRunCommand, "", "latest");
// Remove the first line "name: <your project name>"
composeTemplate = composeTemplate.split("\n").slice(1).join("\n");
callback({
ok: true,
composeTemplate,
});
} catch (e) {
callbackError(e, callback);
}
});
}
View on GitHub (pinned to f809ae192b)
Solutions
- Pass the docker run command as a single string, e.g. 'docker run -d -p 8080:80 nginx'.
- Join array tokens with spaces before emitting: args.join(' ').
- Coerce/guard the value: if (typeof cmd === 'string') emit(...).
Example fix
// before
socket.emit('composerize', ['-d', '-p', '8080:80', 'nginx'], cb);
// after
socket.emit('composerize', 'docker run -d -p 8080:80 nginx', cb); Defensive patterns
Strategy: type-guard
Validate before calling
function isDockerRunCommand(v) {
return typeof v === 'string' && v.trim().startsWith('docker run');
} Type guard
function isString(v) { return typeof v === 'string'; } Try / catch
try {
socket.emit('composerize', cmd, (res) => {
if (!res.ok) throw new TypeError('dockerRunCommand must be a string');
});
} catch (e) {
if (e instanceof TypeError) showInputError(e.message);
} Prevention
- Always pass a single joined string, never arrays of CLI tokens
- Coerce template bindings to string with String(cmd ?? '')
- Check the input box actually has a value before emitting
When it happens
Trigger: Emitting 'composerize' with a non-string first argument: null, undefined, an object like { cmd: '...' }, an array of args, or a number.
Common situations: Frontend binding an unset input model (undefined) to the event; scripts passing an array of CLI tokens instead of one joined string; JSON payloads where the value arrived as an object.
Understand the failure class
Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.
Related errors
- Stack name must be a string.
- Service name must be a string.
- Shell must be a string.
- Data must be an object
- URL must be a string
AI-assisted analysis of louislam/dockge@f809ae192b (2026-08-31).
Data as JSON: /api/errors/e1f9f1d95564d08c.
Report an issue: GitHub.