{"record":{"id":"c38fe768229a1432","repo":"micro/go-micro","slug":"flow-llmgrader-requires-a-flow-model-set-provide","errorCode":null,"errorMessage":"flow: LLMGrader requires a flow model (set Provider/APIKey)","messagePattern":"flow: LLMGrader requires a flow model \\(set Provider/APIKey\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"flow/verify.go","lineNumber":121,"sourceCode":"\t\t\t\tselect {\n\t\t\t\tcase <-time.After(o.Backoff):\n\t\t\t\tcase <-ctx.Done():\n\t\t\t\t\treturn last, ctx.Err()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn stateWithVerification(last, false, feedback, o.MaxAttempts)\n\t}\n}\n\n// LLMGrader returns a grader that asks the flow model to judge the latest output\n// against rubric. The model should answer with pass/fail plus short feedback.\n// It reuses the flow's configured model, so it must run inside a flow.\nfunc LLMGrader(rubric string) Grader {\n\treturn func(ctx context.Context, out State) (bool, string, error) {\n\t\td := depsFrom(ctx)\n\t\tif d == nil || d.model == nil {\n\t\t\treturn false, \"\", fmt.Errorf(\"flow: LLMGrader requires a flow model (set Provider/APIKey)\")\n\t\t}\n\t\tprompt := fmt.Sprintf(\"Grade the latest result against this rubric:\\n%s\\n\\nLatest result:\\n%s\\n\\nAnswer with PASS or FAIL on the first line, followed by one short feedback sentence.\", rubric, out.String())\n\t\tresp, err := d.model.Generate(ctx, &ai.Request{Prompt: prompt})\n\t\tif err != nil {\n\t\t\treturn false, \"\", err\n\t\t}\n\t\treply := resp.Answer\n\t\tif reply == \"\" {\n\t\t\treply = resp.Reply\n\t\t}\n\t\treturn parseGrade(reply)\n\t}\n}\n\nfunc parseGrade(reply string) (bool, string, error) {\n\ttext := strings.TrimSpace(reply)\n\tif text == \"\" {\n\t\treturn false, \"\", fmt.Errorf(\"flow: LLMGrader returned an empty grade\")","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/flow/verify.go#L103-L139","documentation":"flow.LLMGrader returns a Grader that grades output with the flow's configured model, retrieved from the context via depsFrom(ctx). This error is returned at grading time when no flow model is present in the context — i.e. the grader is running outside a configured flow or the flow has no Provider/APIKey set. The LLM call is never attempted.","triggerScenarios":"Running an LLMGrader step when the flow's model was never configured (Provider/APIKey empty), or invoking the grader function directly with a bare context.Context that lacks flow dependency injection.","commonSituations":"Testing the grader outside a real flow run; forgetting to set the flow's model options; building a flow programmatically where model setup was skipped; calling the grader from a non-flow goroutine with a fresh context.","solutions":["Configure the flow's model by setting Provider and APIKey (and any model options) in the flow configuration before running it.","Run the grader only inside a flow execution so the injected dependencies (depsFrom(ctx)) are available.","If testing, inject a mock model into the context/flow deps rather than calling the grader with a plain context."],"exampleFix":"// before\nf := flow.New() // model never configured\nf.Step(flow.Verify(body, flow.LLMGrader(rubric)))\n// after\nf := flow.New(flow.WithModel(\"openai\", os.Getenv(\"OPENAI_API_KEY\")))\nf.Step(flow.Verify(body, flow.LLMGrader(rubric)))","handlingStrategy":"validation","validationCode":"if os.Getenv(\"PROVIDER\") == \"\" || os.Getenv(\"API_KEY\") == \"\" {\n    return errors.New(\"flow model not configured: set Provider and APIKey before using LLMGrader\")\n}","typeGuard":null,"tryCatchPattern":"out, err := step(ctx, in)\nif err != nil && strings.Contains(err.Error(), \"LLMGrader requires a flow model\") {\n    // configure the flow model (Provider/APIKey) and re-run\n}","preventionTips":["Set Provider/APIKey (or a WithModel option) in every flow that uses LLMGrader.","Fail fast at startup with a config check rather than mid-run.","In tests, inject a mock model into flow deps instead of running with a bare context."],"tags":["go","flow","verify","llm","configuration"],"backgroundTag":"missing-model-configuration","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}