{"record":{"id":"cb58ac121fc12de1","repo":"gitroomhq/postiz-app","slug":"failed-to-get-original-link-error","errorCode":null,"errorMessage":"Failed to get original link: ${error}","messagePattern":"Failed to get original link: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"libraries/nestjs-libraries/src/short-linking/providers/kutt.ts","lineNumber":88,"sourceCode":"  }\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 || '';\n    } catch (error) {\n      throw new Error(`Failed to get original link: ${error}`);\n    }\n  }\n\n  async getAllLinksStatistics(\n    id: string,\n    page = 1\n  ): Promise<{ short: string; original: string; clicks: string }[]> {\n    try {\n      const response = await fetch(\n        `${KUTT_API_ENDPOINT}/links?limit=100&skip=${(page - 1) * 100}`,\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();","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/libraries/nestjs-libraries/src/short-linking/providers/kutt.ts#L70-L106","documentation":"Catch-all wrapper in convertShortLinkToLink: any failure resolving a short link (inner HTTP status throw, network error, invalid JSON) is re-thrown as 'Failed to get original link: <cause>'. The underlying reason is embedded in the message text.","triggerScenarios":"The GET /links/{id}/stats call throws for any reason — 404 unknown id, 401 bad key, DNS failure to KUTT_API_ENDPOINT — and the catch re-wraps it.","commonSituations":"Expired/deleted short links being resolved during analytics or repost flows; env misconfiguration between environments (staging key vs prod Kutt instance).","solutions":["Inspect the wrapped cause in the message and fix per status (401 key, 404 unknown link)","Catch this at the call site and fall back to the short link itself or '' since resolution is best-effort","Ensure KUTT_* env vars are consistent across deployments"],"exampleFix":"// before\n} catch (error) {\n  throw new Error(`Failed to get original link: ${error}`);\n}\n\n// after\n} catch (error) {\n  return ''; // resolution is best-effort; degrade gracefully\n}","handlingStrategy":"fallback","validationCode":"if (!process.env.KUTT_API_KEY) return '';","typeGuard":"function isOriginalLinkError(e: unknown): e is Error {\n  return e instanceof Error && e.message.startsWith('Failed to get original link:');\n}","tryCatchPattern":"try {\n  original = await kutt.convertShortLinkToLink(short);\n} catch (error) {\n  this.logger.debug(`Unresolvable short link ${short}: ${error}`);\n  original = short;\n}","preventionTips":["Expect deleted/expired links to fail resolution and default gracefully","Keep KUTT env vars identical across environments to avoid cross-instance 404s"],"tags":["kutt","short-link","error-wrapping"],"backgroundTag":"short-link-provider-failure","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}