n8n-io/n8n · error · Error

Invalid response format from template ${id} API

Error message

Invalid response format from template ${id} API

What it means

Thrown by fetchTemplateByID after a 2xx response whose body fails the isTemplateFetchResponse guard. The guard requires id:number, name:string, and workflow:object (non-null). Like [240], this is a schema/shape failure on an otherwise-OK HTTP response.

Source

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

 */
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[];
}

/**
 * Fetch workflows from templates API and return full workflow data
 * Shared utility used by the get-node-examples and node-details tools
 */
export async function fetchWorkflowsFromTemplates(

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Log response.text() before parsing to capture the actual body for the failing id.
  2. Re-fetch a known-good template id to isolate id-specific corruption from a global schema change.
  3. Check n8n release notes for templates API contract changes.
  4. If a proxy is in play, exclude api.n8n.io from interception.
Defensive patterns

Strategy: type-guard

Validate before calling

function isTemplateFetchResponse(data: unknown): data is TemplateFetchResponse {
  if (typeof data !== 'object' || data === null) return false;
  const o = data as Record<string, unknown>;
  return typeof o.id === 'number' && typeof o.name === 'string'
    && typeof o.workflow === 'object' && o.workflow !== null;
}

Type guard

function isTemplateFetchResponse(data: unknown): data is TemplateFetchResponse {
  if (typeof data !== 'object' || data === null) return false;
  const o = data as Record<string, unknown>;
  return typeof o.id === 'number' && typeof o.name === 'string'
    && typeof o.workflow === 'object' && o.workflow !== null;
}

Try / catch

try {
  const tpl = await fetchTemplateByID(id);
} catch (e) {
  if (e instanceof Error && /Invalid response format from template/.test(e.message)) {
    // body shape changed — log raw and fall back to another template id
  }
  throw e;
}

Prevention

When it happens

Trigger: GET /workflows/templates/{id} returns 200 with a body missing id, name, or workflow; the template endpoint ships a new envelope shape; a proxy replaces the body. The status check at line 105 has passed, so the body itself is the problem.

Common situations: api.n8n.io schema migration drops or renames the workflow field; a partial response from a caching layer; a template that exists in the search index but whose full payload is malformed.

Related errors


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