gitroomhq/postiz-app · error · Error

Failed to create short link: ${error}

Error message

Failed to create short link: ${error}

What it means

Wrapping error thrown by convertLinkToShortLink's catch block: any failure while creating a Kutt short link (network error, JSON parse error, or the inner 'HTTP error! status: N' throw) is re-thrown prefixed with 'Failed to create short link: '. The original cause is stringified into the message.

Source

Thrown at libraries/nestjs-libraries/src/short-linking/providers/kutt.ts:68

    try {
      const response = await fetch(`${KUTT_API_ENDPOINT}/links`, {
        ...getOptions(),
        method: 'POST',
        body: JSON.stringify({
          target: link,
          domain: this.shortLinkDomain,
          reuse: false,
        }),
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const data = await response.json();
      return data.link;
    } catch (error) {
      throw new Error(`Failed to create short link: ${error}`);
    }
  }

  async convertShortLinkToLink(shortLink: string) {
    const linkId = shortLink.split('/').pop();
    
    try {
      const response = await fetch(
        `${KUTT_API_ENDPOINT}/links/${linkId}/stats`,
        getOptions()
      );

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const data = await response.json();
      return data.address || '';

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Read the tail of the message: 'HTTP error! status: 401/403/429/5xx' identifies the root cause; fix per that status
  2. Verify connectivity to KUTT_API_ENDPOINT (curl the health endpoint) if the suffix is a fetch network error
  3. Add exponential-backoff retry for 429/5xx wrapped errors
  4. Fall back to the original long URL when shortening fails so posting is not blocked

Example fix

// before
} catch (error) {
  throw new Error(`Failed to create short link: ${error}`);
}

// after (preserve cause, fail soft upstream)
} catch (error) {
  throw new Error(`Failed to create short link: ${error instanceof Error ? error.message : error}`, { cause: error });
}
Defensive patterns

Strategy: fallback

Validate before calling

if (!process.env.KUTT_API_KEY || !process.env.KUTT_API_ENDPOINT) {
  throw new Error('Kutt short-linking not configured'); // fail fast with a clear message
}

Type guard

function isShortLinkError(e: unknown): e is Error {
  return e instanceof Error && e.message.startsWith('Failed to create short link:');
}

Try / catch

try {
  return await kutt.convertLinkToShortLink(link);
} catch (error) {
  if (/status: (401|403)/.test(String(error))) throw error; // config bug: surface loudly
  return link; // transient failure: use the original URL
}

Prevention

When it happens

Trigger: Any exception inside the try body: non-ok response from POST /links, DNS/network failure to KUTT_API_ENDPOINT, or response body not being JSON. The message chain usually contains the underlying status or fetch error.

Common situations: Same root causes as the inner HTTP error (bad key, unapproved domain), plus transient outages of kutt.it or a self-hosted instance, and rate limiting (429) surfaced through the wrapper.

Related errors


AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27). Data as JSON: /api/errors/b1eb52cbf37c46b3. Report an issue: GitHub.