{"record":{"id":"2c589e83fb8fef6c","repo":"Significant-Gravitas/AutoGPT","slug":"n8n-template-not-found-res-status","errorCode":null,"errorMessage":"n8n template not found (${res.status})","messagePattern":"n8n template not found \\((.+?)\\)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"autogpt_platform/frontend/src/app/(platform)/library/components/LibraryImportDialog/components/ExternalWorkflowTab/fetchWorkflowFromUrl.ts","lineNumber":69,"sourceCode":"    return { ok: true, json };\n  } catch (err) {\n    return {\n      ok: false,\n      error: err instanceof Error ? err.message : \"Failed to fetch workflow.\",\n    };\n  }\n}\n\nasync function fetchN8nWorkflow(templateId: string): Promise<string> {\n  // Only ever fetch from the hardcoded API base + numeric ID.\n  // parseInt + toString round-trips to guarantee the value is purely numeric,\n  // preventing any path-traversal or SSRF via the interpolated segment.\n  const safeId = parseInt(templateId, 10);\n  if (!Number.isFinite(safeId) || safeId <= 0) {\n    throw new Error(\"Invalid template ID\");\n  }\n  const res = await fetch(`${N8N_TEMPLATES_API}/${safeId.toString()}`);\n  if (!res.ok) throw new Error(`n8n template not found (${res.status})`);\n\n  const contentLength = res.headers.get(\"content-length\");\n  if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_BYTES) {\n    throw new Error(\"Response too large.\");\n  }\n\n  const text = await res.text();\n  if (text.length > MAX_RESPONSE_BYTES) throw new Error(\"Response too large.\");\n\n  const data = JSON.parse(text);\n  const template = data?.workflow ?? data;\n  const workflow = template?.workflow ?? template;\n  if (!workflow?.nodes) throw new Error(\"Unexpected n8n API response format\");\n  if (!workflow.name) workflow.name = template?.name ?? data?.name ?? \"\";\n  return JSON.stringify(workflow);\n}\n","sourceCodeStart":51,"sourceCodeEnd":86,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/frontend/src/app/(platform)/library/components/LibraryImportDialog/components/ExternalWorkflowTab/fetchWorkflowFromUrl.ts#L51-L86","documentation":"Thrown by fetchN8nWorkflow when the n8n templates API (N8N_TEMPLATES_API hardcoded base) answers the GET {base}/{numericId} with a non-ok status. The templateId has already been sanitized via parseInt round-trip, so this is purely a server-side outcome: 404 (no such template), 429/403 (rate-limited/blocked), or 5xx on n8n's side. The status code is embedded in the message.","triggerScenarios":"User pastes an n8n template URL whose numeric ID doesn't exist (typo, removed template) → 404; the platform hammers the n8n API and gets rate-limited → 429; n8n API outage → 5xx.","commonSituations":"Importing from an old bookmarked n8n template link whose template was unpublished; shared dev environments hitting n8n rate limits; corporate egress proxies blocking api.n8n.io.","solutions":["Read the embedded status: 404 means the template ID is wrong or gone — verify by opening the URL directly in a browser.","429 → wait and retry; the fetch has no backoff, so clicking Import again after a minute usually works.","5xx → n8n-side outage; retry later or export the workflow JSON from n8n and use the file-import path instead.","Confirm the pasted URL is actually a template URL (numeric ID), not a workflow URL from an n8n instance (those aren't fetchable here)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"function extractTemplateId(url: string): number | null {\n  const m = url.match(/templates\\/(\\d+)/);\n  const id = m ? parseInt(m[1], 10) : NaN;\n  return Number.isFinite(id) && id > 0 ? id : null;\n}","typeGuard":"function isN8nNotFound(err: unknown): boolean {\n  return err instanceof Error && err.message.startsWith(\"n8n template not found\");\n}","tryCatchPattern":"try {\n  const wf = await fetchN8nWorkflow(id);\n} catch (error) {\n  if (isN8nNotFound(error)) {\n    const status = Number(error.message.match(/\\((\\d+)\\)/)?.[1]);\n    if (status === 429 || status >= 500) { /* retry with backoff */ }\n    else toast({ description: \"That template doesn't exist or was removed.\" });\n  }\n}","preventionTips":["Extract and validate the numeric template ID from the URL before fetching (parseInt round-trip, as the code does).","Cache template fetches so double-clicks don't double-hit the n8n API and trip rate limits.","Offer the file-import path in the UI as the fallback whenever URL import fails."],"tags":["n8n","import","http-status","third-party-api","frontend"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}