louislam/dockge · error · Error

Endpoint must be a string:

Error message

Endpoint must be a string: 

What it means

The agent proxy socket handler wraps the `agent` event and type-checks its arguments before forwarding them to agent endpoints. If `endpoint` is not a string it throws 'Endpoint must be a string: <value>'. Unlike most handlers here, this error is only logged (log.warn) — the promise catches it silently for the client.

Source

Thrown at backend/socket-handlers/agent-proxy-socket-handler.ts:18

import { SocketHandler } from "../socket-handler.js";
import { DockgeServer } from "../dockge-server";
import { log } from "../log";
import { checkLogin, DockgeSocket } from "../util-server";
import { AgentSocket } from "../../common/agent-socket";
import { ALL_ENDPOINTS } from "../../common/util-common";

export class AgentProxySocketHandler extends SocketHandler {

    create2(socket : DockgeSocket, server : DockgeServer, agentSocket : AgentSocket) {
        // Agent - proxying requests if needed
        socket.on("agent", async (endpoint : unknown, eventName : unknown, ...args : unknown[]) => {
            try {
                checkLogin(socket);

                // Check Type
                if (typeof(endpoint) !== "string") {
                    throw new Error("Endpoint must be a string: " + endpoint);
                }
                if (typeof(eventName) !== "string") {
                    throw new Error("Event name must be a string");
                }

                if (endpoint === ALL_ENDPOINTS) {      // Send to all endpoints
                    log.debug("agent", "Sending to all endpoints: " + eventName);
                    socket.instanceManager.emitToAllEndpoints(eventName, ...args);

                } else if (!endpoint || endpoint === socket.endpoint) {      // Direct connection or matching endpoint
                    log.debug("agent", "Matched endpoint: " + eventName);
                    agentSocket.call(eventName, ...args);

                } else {
                    log.debug("agent", "Proxying request to " + endpoint + " for " + eventName);
                    await socket.instanceManager.emitToEndpoint(endpoint, eventName, ...args);
                }
            } catch (e) {

View on GitHub (pinned to f809ae192b)

Solutions

  1. Always pass a string endpoint: socket.emit('agent', 'myendpoint', 'eventName', ...args)
  2. Use the ALL_ENDPOINTS sentinel string to broadcast instead of null/undefined
  3. On the client, default the endpoint from socket.endpoint when connected directly

Example fix

// before
socket.emit("agent", endpoint ?? null, "test", data);
// after
socket.emit("agent", endpoint ?? socket.endpoint, "test", data);
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof endpoint !== "string" || !endpoint) { throw new TypeError("agent() requires a string endpoint"); }
socket.emit("agent", endpoint, eventName, ...args);

Type guard

const isEndpoint = (v: unknown): v is string => typeof v === "string" && v.length > 0;

Try / catch

// server only logs this error; client should validate before emitting
if (!isEndpoint(ep)) { console.error("agent event skipped: endpoint must be a string, got", typeof ep); return; }
socket.emit("agent", ep, ev, ...args);

Prevention

When it happens

Trigger: Emitting socket event `agent` with a non-string first argument, e.g. socket.emit('agent', null, 'test', payload), or passing an object endpoint, or omitting it (undefined).

Common situations: Client sending endpoint as undefined because it never bound to an endpoint; JSON payloads where endpoint was nested; custom scripts calling the raw socket API without the frontend wrapper.

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