{"record":{"id":"b1eb52cbf37c46b3","repo":"gitroomhq/postiz-app","slug":"failed-to-create-short-link-error","errorCode":null,"errorMessage":"Failed to create short link: ${error}","messagePattern":"Failed to create short link: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"libraries/nestjs-libraries/src/short-linking/providers/kutt.ts","lineNumber":68,"sourceCode":"    try {\n      const response = await fetch(`${KUTT_API_ENDPOINT}/links`, {\n        ...getOptions(),\n        method: 'POST',\n        body: JSON.stringify({\n          target: link,\n          domain: this.shortLinkDomain,\n          reuse: false,\n        }),\n      });\n\n      if (!response.ok) {\n        throw new Error(`HTTP error! status: ${response.status}`);\n      }\n\n      const data = await response.json();\n      return data.link;\n    } catch (error) {\n      throw new Error(`Failed to create short link: ${error}`);\n    }\n  }\n\n  async convertShortLinkToLink(shortLink: string) {\n    const linkId = shortLink.split('/').pop();\n    \n    try {\n      const response = await fetch(\n        `${KUTT_API_ENDPOINT}/links/${linkId}/stats`,\n        getOptions()\n      );\n\n      if (!response.ok) {\n        throw new Error(`HTTP error! status: ${response.status}`);\n      }\n\n      const data = await response.json();\n      return data.address || '';","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/libraries/nestjs-libraries/src/short-linking/providers/kutt.ts#L50-L86","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the tail of the message: 'HTTP error! status: 401/403/429/5xx' identifies the root cause; fix per that status","Verify connectivity to KUTT_API_ENDPOINT (curl the health endpoint) if the suffix is a fetch network error","Add exponential-backoff retry for 429/5xx wrapped errors","Fall back to the original long URL when shortening fails so posting is not blocked"],"exampleFix":"// before\n} catch (error) {\n  throw new Error(`Failed to create short link: ${error}`);\n}\n\n// after (preserve cause, fail soft upstream)\n} catch (error) {\n  throw new Error(`Failed to create short link: ${error instanceof Error ? error.message : error}`, { cause: error });\n}","handlingStrategy":"fallback","validationCode":"if (!process.env.KUTT_API_KEY || !process.env.KUTT_API_ENDPOINT) {\n  throw new Error('Kutt short-linking not configured'); // fail fast with a clear message\n}","typeGuard":"function isShortLinkError(e: unknown): e is Error {\n  return e instanceof Error && e.message.startsWith('Failed to create short link:');\n}","tryCatchPattern":"try {\n  return await kutt.convertLinkToShortLink(link);\n} catch (error) {\n  if (/status: (401|403)/.test(String(error))) throw error; // config bug: surface loudly\n  return link; // transient failure: use the original URL\n}","preventionTips":["Parse the wrapped cause from the message to distinguish config errors (401/403) from transient ones (5xx/network)","Wrap shortening with a timeout so a hung Kutt API cannot stall the post workflow"],"tags":["kutt","short-link","error-wrapping","network"],"backgroundTag":"short-link-provider-failure","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}