paperclipai/paperclip · error · ProtocolError

malformed_request

malformed_request

Error message

request must be a JSON object

What it means

asObject guard in the broker's request decoder: the JSON-decoded request body is not a plain object (it is an array, a scalar, or null). The ProtocolError('malformed_request') fails before any field is read, since nothing downstream can trust the shape.

Source

Thrown at packages/tailscale-https-broker/src/protocol.ts:56

export class ProtocolError extends Error {
  constructor(
    readonly code:
      | "unsupported_version"
      | "malformed_request"
      | "unknown_operation"
      | "invalid_runtime_id"
      | "invalid_port",
    message: string,
    readonly requestId: string | null = null,
  ) {
    super(message);
    this.name = "ProtocolError";
  }
}

function asObject(value: unknown): Record<string, unknown> {
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
    throw new ProtocolError("malformed_request", "request must be a JSON object");
  }
  return value as Record<string, unknown>;
}

function requireStringField(
  obj: Record<string, unknown>,
  field: string,
  re: RegExp,
  code: ProtocolError["code"],
  requestId: string | null,
): string {
  const value = obj[field];
  if (typeof value !== "string" || !re.test(value)) {
    throw new ProtocolError(code, `invalid or missing field: ${field}`, requestId);
  }
  return value;
}

View on GitHub (pinned to 120ae5428f)

Solutions

  1. Send the request as a JSON object with the required protocol fields.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/tailscale-https-broker/src/protocol.ts:56 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@120ae5428f (2026-08-18). Data as JSON: /api/errors/42c8c5f5322ea9b2. Report an issue: GitHub.