n8n-io/n8n · error · Error
Invalid response format from templates API
Error message
Invalid response format from templates API
What it means
Thrown by fetchTemplateList after a successful HTTP 200 from https://api.n8n.io/api/templates/search when the JSON body fails the isTemplateSearchResponse type guard. The guard requires the body to be an object containing totalWorkflows:number and workflows:array. A 2xx response carrying an HTML error page, a maintenance banner, or a backwards-incompatible schema change will trip it.
Source
Thrown at packages/@n8n/ai-workflow-builder.ee/src/tools/web/templates.ts:86
}): Promise<TemplateSearchResponse> {
const queryString = buildSearchQueryString(query);
const url = `${N8N_API_BASE_URL}/templates/search${queryString ? `?${queryString}` : ''}`;
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
});
if (!response.ok) {
throw new Error(`Failed to fetch templates: ${response.status} ${response.statusText}`);
}
const data: unknown = await response.json();
if (!isTemplateSearchResponse(data)) {
throw new Error('Invalid response format from templates API');
}
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',
},
});
View on GitHub (pinned to 5ac6606e81)
Solutions
- Inspect the actual response body (log response.text() before parsing) to see what api.n8n.io returned.
- Verify the endpoint and shape against the current n8n templates API documentation.
- If behind a proxy, bypass it and retry to rule out response rewriting.
- If you maintain a mock server, ensure it returns { totalWorkflows: number, workflows: [] }.
Example fix
// before
const data: unknown = await response.json();
if (!isTemplateSearchResponse(data)) {
throw new Error('Invalid response format from templates API');
}
// after - surface the body for diagnosis
const text = await response.text();
let data: unknown;
try { data = JSON.parse(text); } catch { throw new Error(`Templates API returned non-JSON body: ${text.slice(0, 200)}`); }
if (!isTemplateSearchResponse(data)) {
throw new Error(`Unexpected templates API shape: ${JSON.stringify(Object.keys(data ?? {}))}`);
} Defensive patterns
Strategy: type-guard
Validate before calling
// Validate before trusting the API shape — re-use the same predicate
import { isTemplateSearchResponse } from '@/tools/web/templates';
function assertSearchResponse(raw: unknown): TemplateSearchResponse {
if (!isTemplateSearchResponse(raw)) {
throw new Error(`Unexpected templates API shape: ${JSON.stringify(Object.keys((raw as any) ?? {}))}`);
}
return raw;
} Type guard
function isTemplateSearchResponse(data: unknown): data is TemplateSearchResponse {
if (typeof data !== 'object' || data === null) return false;
const obj = data as Record<string, unknown>;
return typeof obj.totalWorkflows === 'number' && Array.isArray(obj.workflows);
} Try / catch
try {
const result = await fetchTemplateList(query);
// use result
} catch (e) {
if (e instanceof Error && e.message.startsWith('Invalid response format from templates API')) {
// degrade gracefully — surface 'templates unavailable' to the caller
}
throw e;
} Prevention
- Always type-guard upstream API responses before use, even on 200.
- Log response.text() on validation failure so schema drift is diagnosable.
- Pin templates API integration tests against recorded fixtures to catch contract changes early.
When it happens
Trigger: GET https://api.n8n.io/api/templates/search returns 200 with a body lacking totalWorkflows or workflows (e.g. CDN serves an HTML error page, the API ships a schema change, or a caching proxy returns a stale/mismatched payload). The response.ok check at line 80 has already passed, so only shape mismatches reach this throw.
Common situations: n8n.cloud or api.n8n.io deploys a templates API schema change; a corporate proxy intercepts and rewrites the JSON; an incident returns a JSON error object instead of the search envelope; local development with a mocked API that forgets the totalWorkflows field.
Related errors
- Invalid response format from template ${id} API
- Failed to fetch template ${id}: ${response.status} ${respons
- Failed to fetch templates: ${response.status} ${response.sta
- Failed to fetch provider catalog: ${response.statusText}
- Supabase upsert failed: ${error.message}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/a0a370d63f5351c8.
Report an issue: GitHub.