paperclipai/paperclip · error · Error

Request failed with status ${response.status}

Error message

Request failed with status ${response.status}

What it means

streamPluginBridge throws when the GET /api/plugins/{pluginId}/bridge/stream/{channel} response is not ok. It uses the trimmed response body as the message, falling back to a status-code string when the body is empty.

Source

Thrown at cli/src/commands/client/plugin.ts:974

  apiBase: string,
  apiKey: string | undefined,
  pluginId: string,
  channel: string,
  durationMs: number | undefined,
): Promise<void> {
  const controller = new AbortController();
  const timer = durationMs === undefined ? null : setTimeout(() => controller.abort(), durationMs);
  try {
    const response = await fetch(buildApiUrl(
      apiBase,
      `/api/plugins/${encodeURIComponent(pluginId)}/bridge/stream/${encodeURIComponent(channel)}`,
    ), {
      headers: apiKey ? { authorization: `Bearer ${apiKey}` } : undefined,
      signal: controller.signal,
    });
    if (!response.ok) {
      const text = await response.text();
      throw new Error(text.trim() || `Request failed with status ${response.status}`);
    }
    if (!response.body) return;
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    while (true) {
      const { value, done } = await reader.read();
      if (done) break;
      if (value) process.stdout.write(decoder.decode(value, { stream: true }));
    }
    const trailing = decoder.decode();
    if (trailing) process.stdout.write(trailing);
  } catch (error) {
    if (error instanceof Error && error.name === "AbortError") return;
    throw error;
  } finally {
    if (timer) clearTimeout(timer);
  }
}

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Verify pluginId via `paperclipai plugin list`.
  2. Confirm the channel name with the plugin author/docs.
  3. Check auth (re-run connect if the token expired).
  4. Ensure the plugin runtime is healthy on the server side.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await streamPluginBridge(apiBase, apiKey, pluginId, channel, durationMs);
} catch (err) {
  const msg = err instanceof Error ? err.message : String(err);
  if (/404/.test(msg)) console.error('Unknown plugin or channel; verify with `paperclipai plugin list`.');
  if (/401|403/.test(msg)) await refreshToken();
  throw err;
}

Prevention

When it happens

Trigger: Streaming a plugin bridge channel that returns non-2xx: unknown pluginId, unknown channel, plugin not running, auth failure, or server error.

Common situations: Plugin not installed or not enabled for the company; typo in channel name; expired API key; plugin process offline.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/cfbcd74e933de92c. Report an issue: GitHub.