{"record":{"id":"967ed43cccddca81","repo":"n8n-io/n8n","slug":"output-error-errors-0","errorCode":null,"errorMessage":"output.error.errors[0]","messagePattern":"output\\.error\\.errors\\[0\\]","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"packages/cli/src/controller.registry.ts","lineNumber":110,"sourceCode":"\t\t\tconst handler = async (req: Request, res: Response) => {\n\t\t\t\tif (route.cors) {\n\t\t\t\t\tconst corsService = Container.get(CorsService);\n\t\t\t\t\tconst corsOptions = route.cors === true ? {} : route.cors;\n\t\t\t\t\tcorsService.applyCorsHeaders(req, res, corsOptions);\n\t\t\t\t}\n\n\t\t\t\tconst args: unknown[] = [req, res];\n\t\t\t\tfor (let index = 0; index < route.args.length; index++) {\n\t\t\t\t\tconst arg = route.args[index];\n\t\t\t\t\tif (!arg) continue;\n\t\t\t\t\tif (arg.type === 'param') args.push(req.params[arg.key]);\n\t\t\t\t\telse if (['body', 'query'].includes(arg.type)) {\n\t\t\t\t\t\tconst paramType = argTypes[index] as ZodClass;\n\t\t\t\t\t\tif (paramType && 'safeParse' in paramType) {\n\t\t\t\t\t\t\tconst output = paramType.safeParse(req[arg.type]);\n\t\t\t\t\t\t\tif (output.success) args.push(output.data);\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\treturn res.status(400).json(output.error.errors[0]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else throw new UnexpectedError('Unknown arg type: ' + arg.type);\n\t\t\t\t}\n\t\t\t\treturn await controller[handlerName](...args);\n\t\t\t};\n\n\t\t\tconst bodyArgIdx = route.args.findIndex((arg) => arg?.type === 'body');\n\t\t\tconst bodyArgType = bodyArgIdx !== -1 ? (argTypes[bodyArgIdx] as ZodClass) : undefined;\n\n\t\t\tconst middlewares = this.buildMiddlewares(route, controllerMiddlewares, bodyArgType);\n\t\t\tconst finalHandler = route.usesTemplates\n\t\t\t\t? async (req: Request, res: Response) => {\n\t\t\t\t\t\tawait handler(req, res);\n\t\t\t\t\t}\n\t\t\t\t: send(handler);\n\n\t\t\trouter[route.method](route.path, ...middlewares, finalHandler);","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/cli/src/controller.registry.ts#L92-L128","documentation":"Not a thrown error but the 400 response body returned by the controller registry when a request `body` or `query` fails Zod validation against the route's `@Body`/`@Query` DTO. The registry calls `paramType.safeParse(req[arg.type])`; on failure it returns `output.error.errors[0]` — the first Zod issue object — as JSON with HTTP 400. The literal message field is the dynamic property name `output.error.errors[0]`.","triggerScenarios":"POSTing/PATCHing to any REST endpoint whose handler declares a Zod DTO and the payload violates the schema (missing required field, wrong type, failed regex, out-of-range number).","commonSituations":"Client sends a stale DTO shape after a backend version bump; missing required fields; wrong enum value; string sent where a number is expected.","solutions":["Inspect the returned `errors[0]` object — it carries `path`, `code`, and `message` identifying the offending field.","Compare your payload against the route's DTO in `@n8n/api-types`.","Update the client to match the current schema, or upgrade/downgrade to a matching backend version."],"exampleFix":"// before: 400 because `name` missing\nfetch('/rest/v1/projects', { method:'POST', body: JSON.stringify({}) })\n// after\nfetch('/rest/v1/projects', { method:'POST', body: JSON.stringify({ name: 'My Project' }) })","handlingStrategy":"validation","validationCode":"const parsed = Dto.safeParse(payload);\nif (!parsed.success) {\n  const issue = parsed.error.issues[0];\n  throw new Error(`Validation failed at ${issue.path.join('.')}: ${issue.message}`);\n}","typeGuard":null,"tryCatchPattern":"try { await api.post('/x', payload); } catch (e) { if (e.response?.status === 400 && e.response.data?.path) { console.error('Fix field', e.response.data.path); } else throw e; }","preventionTips":["Generate the client DTOs from the same `@n8n/api-types` package the backend uses.","Add a Zod safeParse step in integration tests for every payload you send."],"tags":["api","validation","zod","rest","user-error"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}