{"record":{"id":"a07039c30d726d08","repo":"n8n-io/n8n","slug":"eval-this-evalname-uses-judge-but-no-mode","errorCode":null,"errorMessage":"Eval \"${this.evalName}\" uses .judge() but no .model() was set","messagePattern":"Eval \"(.+?)\" uses \\.judge\\(\\) but no \\.model\\(\\) was set","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/sdk/eval.ts","lineNumber":119,"sourceCode":"\t\t\tthrow new Error(`Eval \"${this.evalName}\": cannot use both .check() and .judge()`);\n\t\t}\n\t\tthis.judgeFn = fn;\n\t\treturn this;\n\t}\n\n\t/** The eval name. */\n\tget name(): string {\n\t\treturn this.evalName;\n\t}\n\n\t/** @internal Build the eval into a runnable form. */\n\tprotected build(): BuiltEval {\n\t\tif (!this.checkFn && !this.judgeFn) {\n\t\t\tthrow new Error(`Eval \"${this.evalName}\" requires either .check() or .judge()`);\n\t\t}\n\n\t\tif (this.judgeFn && !this.modelId) {\n\t\t\tthrow new Error(`Eval \"${this.evalName}\" uses .judge() but no .model() was set`);\n\t\t}\n\n\t\tconst name = this.evalName;\n\t\tconst desc = this.desc;\n\n\t\tif (this.checkFn) {\n\t\t\tconst checkFn = this.checkFn;\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\tdescription: desc,\n\t\t\t\tevalType: 'check' as const,\n\t\t\t\tmodelId: this.modelId ?? null,\n\t\t\t\tcredentialName: this.credentialName ?? null,\n\t\t\t\t_run: async (input: EvalInput) => await checkFn(input),\n\t\t\t};\n\t\t}\n\n\t\t// LLM-as-judge mode","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/sdk/eval.ts#L101-L137","documentation":"First of two guards enforcing that LLM-as-judge evals declare a model. Thrown at the top of Eval.build() when this.judgeFn is set but this.modelId is undefined. The builder cannot construct the judge AgentRuntime without a model id.","triggerScenarios":"Calling .judge(fn) without a preceding .model('provider/name'), then triggering build via .run() or a runner.","commonSituations":"Forgetting .model() when porting a check-style eval to judge; setting .model(undefined) conditionally; relying on a parent agent's model to propagate (it does not).","solutions":["Call .model('anthropic/claude-haiku-4-5') (or another model id) before .judge().","Also call .credential(name) so the judge runtime can resolve an API key.","Validate eval config in tests by asserting modelId is set whenever judgeFn is."],"exampleFix":"// before\nconst e = new Eval('corr').judge(async ({ llm }) => { ... });\n// after\nconst e = new Eval('corr')\n  .model('anthropic/claude-haiku-4-5')\n  .credential('anthropic')\n  .judge(async ({ llm }) => { ... });","handlingStrategy":"validation","validationCode":"function assertJudgeModel(e: { judgeFn?: unknown; modelId?: string }) {\n  if (e.judgeFn && !e.modelId) {\n    throw new Error('Eval uses .judge() without .model(); add .model(provider/name)');\n  }\n}","typeGuard":"function judgeEvalHasModel(e: { judgeFn?: unknown; modelId?: string }): boolean {\n  return typeof e.judgeFn === 'function' && typeof e.modelId === 'string' && e.modelId.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Treat .model() and .credential() as mandatory whenever .judge() is used.","Wrap judge-eval construction in a factory that requires model and credential as parameters."],"tags":["eval","judge","model","builder"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}