gitroomhq/postiz-app · warning · Error

HTTP error! status: ${response.status}

Error message

HTTP error! status: ${response.status}

What it means

Thrown by the Kutt short-link provider when the Kutt server's GET /links/{id}/stats endpoint returns a non-2xx status (e.g. 401 for a bad API key, 404 for an unknown link id). The code checks response.ok and throws a generic HTTP error with the status code embedded. Inside linksStatistics this is caught and the link is reported with 0 clicks, but the raw error surfaces anywhere the throw escapes.

Source

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

  },
});

export class Kutt implements ShortLinking {
  shortLinkDomain = KUTT_SHORT_LINK_DOMAIN;

  async linksStatistics(links: string[]) {
    return Promise.all(
      links.map(async (link) => {
        const linkId = link.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 {
            short: link,
            original: data.address || '',
            clicks: data.lastDay?.stats?.reduce((total: number, stat: any) => total + stat, 0)?.toString() || '0',
          };
        } catch (error) {
          return {
            short: link,
            original: '',
            clicks: '0',
          };
        }
      })
    );

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Verify KUTT_API_KEY and KUTT_API_ENDPOINT env vars are set and the key belongs to the same Kutt instance that created the short links
  2. Test the key directly: curl -H 'X-API-Key: $KUTT_API_KEY' $KUTT_API_ENDPOINT/links/<id>/stats and confirm 200
  3. If a 404, confirm the link id (last path segment) actually exists in that Kutt account
  4. Add retry/backoff for transient 5xx from the Kutt server

Example fix

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

// after (actionable status info)
if (!response.ok) {
  throw new Error(`Kutt stats request failed for ${linkId}: ${response.status} ${response.statusText}`);
}
Defensive patterns

Strategy: fallback

Validate before calling

import { isSafePublicHttpsUrl } from './url.util';

async function canFetchKuttStats(link: string, apiKey?: string): Promise<boolean> {
  if (!apiKey) return false; // avoid guaranteed 401
  try { return isSafePublicHttpsUrl(link); } catch { return false; }
}

Type guard

function isKuttLink(v: string): boolean {
  return /^https:\/\/[\w.-]+\/([\w-]+)$/.test(v);
}

Try / catch

// linksStatistics already degrades to { clicks: '0' } per-link on failure;
// mirror that at call sites:
try {
  const stats = await kutt.linksStatistics(links);
} catch {
  const stats = links.map((l) => ({ short: l, original: '', clicks: '0' }));
}

Prevention

When it happens

Trigger: Calling linksStatistics(['https://kutt.it/abc123']) with a missing/invalid KUTT_API_KEY (401), a link id that does not exist in the Kutt account (404), or a wrong/unreachable KUTT_API_ENDPOINT (404/5xx from a proxy).

Common situations: KUTT_API_KEY env var not set (it is passed raw from process.env with no validation), self-hosting Kutt at a custom KUTT_API_ENDPOINT that is down or misrouted, links created under a different Kutt account/domain than the configured key.

Related errors


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