n8n-io/n8n · error · Error

Failed to fetch template ${id}: ${response.status} ${respons

Error message

Failed to fetch template ${id}: ${response.status} ${response.statusText}

What it means

Thrown by fetchTemplateByID when the GET to https://api.n8n.io/api/workflows/templates/{id} returns a non-2xx status (response.ok is false). The message embeds the template id and the HTTP status/statusText for diagnosis. This is the upstream counterpart to [242]; it fires before any body parsing.

Source

Thrown at packages/@n8n/ai-workflow-builder.ee/src/tools/web/templates.ts:106

	return data;
}

/**
 * Fetch a specific workflow template by ID from n8n API
 */
export async function fetchTemplateByID(id: number): Promise<TemplateFetchResponse> {
	const url = `${N8N_API_BASE_URL}/workflows/templates/${id}`;

	const response = await fetch(url, {
		method: 'GET',
		headers: {
			'Content-Type': 'application/json',
			Accept: 'application/json',
		},
	});

	if (!response.ok) {
		throw new Error(`Failed to fetch template ${id}: ${response.status} ${response.statusText}`);
	}

	const data: unknown = await response.json();
	if (!isTemplateFetchResponse(data)) {
		throw new Error(`Invalid response format from template ${id} API`);
	}
	return data;
}

/**
 * Result of fetching workflows from templates
 */
export interface FetchWorkflowsResult {
	workflows: WorkflowMetadata[];
	totalFound: number;
	templateIds: number[];
}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Read the embedded status code: 404 means the id is gone, 5xx means retry later, 429 means back off.
  2. If the id came from a previous search call, re-run the search to get a fresh id.
  3. For transient 5xx/429, retry with exponential backoff.
  4. Confirm the id is a valid number and the template still exists on https://n8n.io/workflows.

Example fix

// before
if (!response.ok) {
  throw new Error(`Failed to fetch template ${id}: ${response.status} ${response.statusText}`);
}

// after - retry once on transient failures
if (!response.ok) {
  if (response.status >= 500 || response.status === 429) {
    throw new OperationalError(`Template ${id} unavailable (${response.status}), retry later`);
  }
  throw new Error(`Failed to fetch template ${id}: ${response.status} ${response.statusText}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the id is a positive integer before calling
function assertTemplateId(id: number) {
  if (!Number.isInteger(id) || id <= 0) {
    throw new Error(`Invalid template id: ${id}`);
  }
}

Type guard

const isOkStatus = (status: number) => status >= 200 && status < 300;

Try / catch

try {
  const tpl = await fetchTemplateByID(id);
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e);
  if (/Failed to fetch template .*: 404/.test(msg)) {
    // template gone — pick another from search results
  } else if (/: 5\d\d/.test(msg) || /: 429/.test(msg)) {
    // transient — retry with backoff
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Requesting a template id that does not exist (404), api.n8n.io is degraded (5xx), rate-limited (429), or the id passed in is NaN/garbage producing an unexpected path. Any non-2xx from the templates endpoint reaches this throw.

Common situations: The AI workflow builder resolves a template id from search results that has since been deleted; a stale bookmark/template id is hardcoded; api.n8n.io has a partial outage; a network middlebox returns a 502.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/7ca17bd5bfa10c33. Report an issue: GitHub.