nexu-io/open-design · error · CollabCloudError

collab cloud error ${status} (${code})

Error message

collab cloud error ${status} (${code})

What it means

Thrown inside the client's request() helper as a CollabCloudError when the collab cloud HTTP response is not ok. It carries response.status, a code parsed from payload.error (or 'unknown'), and the upstream payload.message. The class is exported (CollabCloudError) with name set for instanceof checks, so callers can branch on status/code.

Source

Thrown at apps/daemon/src/integrations/collab-cloud.ts:106

  ): Promise<{ status: number; payload: T; etag: string | null }> {
    const controller = new AbortController();
    const timeout = setTimeout(() => controller.abort(), timeoutMs);
    try {
      const response = await fetchImpl(new URL(path, config!.baseUrl), {
        method,
        headers: authHeaders(extraHeaders),
        ...(body === undefined ? {} : { body: JSON.stringify(body) }),
        signal: controller.signal,
      });
      const etag = response.headers.get('etag');
      if (response.status === 304) {
        return { status: 304, payload: {} as T, etag };
      }
      const text = await response.text();
      const payload = text ? JSON.parse(text) : {};
      if (!response.ok) {
        const code = typeof payload?.error === 'string' ? payload.error : 'unknown';
        throw new CollabCloudError(response.status, code, payload?.message);
      }
      return { status: response.status, payload: payload as T, etag };
    } finally {
      clearTimeout(timeout);
    }
  }

  return {
    isConfigured(): boolean {
      return true;
    },

    /** Register (idempotently upsert) a member's directory entry. */
    async registerMember(
      teamId: string,
      memberId: string,
      input: CollabCloudMemberRegistration,
    ): Promise<CollabCloudMemberDirectoryEntry> {

View on GitHub (pinned to 5be4028344)

Solutions

  1. Catch CollabCloudError by instanceof and branch on err.status / err.code: 401/403 → fix token, 404 → fix ids, 5xx → retry/back off.
  2. Verify OD_COLLAB_CLOUD_TOKEN matches the hub's issued token and that baseUrl matches the relay.
  3. For transient 5xx, wrap the call in a bounded retry with exponential backoff.

Example fix

// before
await client.registerMember(teamId, memberId, input);

// after
try {
  await client.registerMember(teamId, memberId, input);
} catch (err) {
  if (err instanceof CollabCloudError && (err.status === 401 || err.status === 403)) {
    // token/permission problem — surface to operator, do not retry
  }
  throw err;
}
Defensive patterns

Strategy: try-catch

Type guard

import { CollabCloudError } from '../integrations/collab-cloud.js';

function isCollabCloudError(err: unknown): err is CollabCloudError {
  return err instanceof CollabCloudError;
}

function isAuthError(err: unknown): boolean {
  return isCollabCloudError(err) && (err.status === 401 || err.status === 403);
}

Try / catch

try {
  await client.registerMember(teamId, memberId, input);
} catch (err) {
  if (err instanceof CollabCloudError) {
    // branch on err.status and err.code; do not retry 4xx auth/not-found
  }
  throw err;
}

Prevention

When it happens

Trigger: Any collab cloud call (registerMember, pull, etc.) whose upstream PUT/GET returns 4xx/5xx, e.g. 401 (bad/missing OD_COLLAB_CLOUD_TOKEN), 403, 404 team/member path, or 5xx from the relay. Also triggered when the upstream returns a non-JSON body parsed into an object lacking an error field (code becomes 'unknown').

Common situations: Bearer token expired or rotated but OD_COLLAB_CLOUD_TOKEN not updated; team/member id mismatch against the relay's directory; relay/network returning 502/503; wrong baseUrl pointing at a different hub that rejects the token.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/e33fef697c2afaee. Report an issue: GitHub.