dubinc/dub · error

(parsedData as APIError).error.message

Error message

(parsedData as APIError).error.message

What it means

parseApiResponse inspects the response content-type; for JSON bodies containing an `error` key it throws an Error whose message is the API's error message from the Dub API error payload. This surfaces the real server-side reason (auth, validation, not found, rate limit) to the caller instead of returning a failed payload as data.

Source

Thrown at packages/cli/src/utils/parser.ts:13

import type { APIError } from "@/types";
import type { Response as NodeFetchResponse } from "node-fetch";

type AnyResponse = Response | NodeFetchResponse;

export async function parseApiResponse<T>(response: AnyResponse): Promise<T> {
  const contentType = response.headers.get("content-type");

  if (contentType?.includes("application/json")) {
    const parsedData = await response.json();

    if ("error" in parsedData) {
      throw new Error((parsedData as APIError).error.message);
    }

    return parsedData as T;
  }

  const textData = await response.text();

  throw new Error(textData);
}

View on GitHub (pinned to f216b94a24)

Solutions

  1. Read the thrown message — it is the API's own message — and fix the request accordingly (token, domain name, params).
  2. Re-authenticate with `dub login` if the message indicates unauthorized/invalid token.
  3. Validate request payloads (domain format, required fields) before sending.
  4. Check api.dub.co status / retry with backoff if the message indicates rate limiting or server error.

Example fix

// before
const res = await createDomain({ slug: 'my domain!' });
// after (validate before calling)
if (!/^[a-z0-9.-]+$/.test(slug)) throw new Error('invalid domain slug');
const res = await createDomain({ slug });
Defensive patterns

Strategy: try-catch

Type guard

function isApiError(data: unknown): data is { error: { code: string; message: string } } {
  return typeof data === "object" && data !== null && "error" in data && typeof (data as any).error?.message === "string";
}

Try / catch

try {
  const domains = await parseApiResponse(response);
} catch (e) {
  const msg = (e as Error).message;
  if (/unauthorized|invalid token/i.test(msg)) {
    await relogin();
  } else if (/rate.?limit/i.test(msg)) {
    await sleep(backoff);
  } else {
    console.error("Dub API error:", msg);
  }
}

Prevention

When it happens

Trigger: Any call routed through parseApiResponse (`dub domains` / defaultDomains) where the Dub API returns a JSON body like {"error":{"code":"bad_request","message":"..."}} with a 4xx/5xx status.

Common situations: Expired or wrong access token (401 unauthorized); invalid domain payload (422); referencing a nonexistent resource; hitting rate limits (429).

Related errors


AI-assisted analysis of dubinc/dub@f216b94a24 (2026-08-31). Data as JSON: /api/errors/ff3fdae590facc3a. Report an issue: GitHub.