paperclipai/paperclip · error

PAPERCLIP_VITE_HMR_PROTOCOL must be ws or wss

Error message

PAPERCLIP_VITE_HMR_PROTOCOL must be ws or wss

What it means

Environment-variable validation in resolveViteHmrProtocol: PAPERCLIP_VITE_HMR_PROTOCOL is set but is neither 'ws' nor 'wss' (case-sensitive after trim/lowercase handling upstream). The value is passed straight into Vite's HMR config which only accepts those two protocols, so dev-server startup aborts with this guard.

Source

Thrown at server/src/app.ts:166

export function isDatabaseConnectionUnavailableError(err: unknown): boolean {
  const error = err as { code?: unknown; message?: unknown; cause?: unknown };
  if (error?.code === "ECONNREFUSED") return true;
  return Boolean(error?.cause && isDatabaseConnectionUnavailableError(error.cause));
}

export function resolveViteHmrPort(serverPort: number): number {
  return derivePaperclipViteHmrPort(serverPort);
}

export function resolveViteHmrHost(bindHost: string): string | undefined {
  const normalized = bindHost.trim().toLowerCase();
  if (
    normalized === "0.0.0.0"
    || normalized === "::"
    || normalized === "127.0.0.1"
    || normalized === "::1"
    || normalized === "localhost"
  ) return undefined;
  return bindHost;
}

export function resolveViteHmrProtocol(value: string | undefined): "ws" | "wss" | undefined {
  if (!value) return undefined;
  if (value === "ws" || value === "wss") return value;
  throw new Error("PAPERCLIP_VITE_HMR_PROTOCOL must be ws or wss");
}

export function listenViteHmrServer(server: HttpServer, port: number, bindHost: string): Promise<void> {
  return new Promise((resolve, reject) => {
    const onError = (error: Error) => {
      server.off("listening", onListening);
      reject(error);
    };
    const onListening = () => {
      server.off("error", onError);

View on GitHub (pinned to 01ad858492)

Solutions

  1. Set PAPERCLIP_VITE_HMR_PROTOCOL to ws or wss.
  2. Unset PAPERCLIP_VITE_HMR_PROTOCOL to use the default.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/app.ts:162 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18). Data as JSON: /api/errors/f2653a58a59f29e6. Report an issue: GitHub.