{"record":{"id":"34ccaaaa17fe330d","repo":"micro/go-micro","slug":"llm-step-requires-a-flow-model-set-provider-apike","errorCode":null,"errorMessage":"LLM step requires a flow model (set Provider/APIKey)","messagePattern":"LLM step requires a flow model \\(set Provider/APIKey\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"flow/steps.go","lineNumber":315,"sourceCode":"\treturn func(ctx context.Context, in State) (State, error) {\n\t\treply, err := a2a.NewClient(url).Send(ctx, in.String())\n\t\tif err != nil {\n\t\t\treturn in, err\n\t\t}\n\t\tin.Data = []byte(reply)\n\t\treturn in, nil\n\t}\n}\n\n// LLM returns a StepFunc that runs one augmented-LLM turn: it renders the\n// prompt template against the current state (.Data, .Stage), lets the\n// model call the flow's services as tools, and stores the reply as the\n// new Data.\nfunc LLM(prompt string) StepFunc {\n\treturn func(ctx context.Context, in State) (State, error) {\n\t\td := depsFrom(ctx)\n\t\tif d == nil || d.model == nil {\n\t\t\treturn in, fmt.Errorf(\"LLM step requires a flow model (set Provider/APIKey)\")\n\t\t}\n\t\ttext := prompt\n\t\tif tmpl, err := template.New(\"step\").Parse(prompt); err == nil {\n\t\t\tvar buf bytes.Buffer\n\t\t\tif tmpl.Execute(&buf, map[string]string{\"Data\": in.String(), \"Stage\": in.Stage}) == nil {\n\t\t\t\ttext = buf.String()\n\t\t\t}\n\t\t}\n\t\tvar tools []ai.Tool\n\t\tif d.tools != nil {\n\t\t\ttools, _ = d.tools.Discover()\n\t\t}\n\t\tresp, err := d.model.Generate(ctx, &ai.Request{Prompt: text, Tools: tools})\n\t\tif err != nil {\n\t\t\treturn in, err\n\t\t}\n\t\treply := resp.Answer\n\t\tif reply == \"\" {","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/flow/steps.go#L297-L333","documentation":"The LLM step helper needs a configured language model on the flow's dependencies. Before executing the prompt it resolves the deps from the context; if there are no deps or the deps carry a nil model, the step fails immediately with this error. It exists so a missing model config surfaces as a clear message instead of a nil-pointer panic deep inside the model call.","triggerScenarios":"Calling flow.LLM(prompt) as a StepFunc when the flow was built without Provider/APIKey options, or when the context passed to the step carries no flow deps (d == nil), e.g. invoking the step function directly outside a configured Flow run.","commonSituations":"Developers add an LLM step to a flow but forget to configure the model options (Provider/APIKey) on the flow; or they test the step function standalone with a plain context.Context that never had deps attached; or the provider env credentials are missing so the model was never constructed.","solutions":["Configure the flow's model: pass Provider and APIKey options when constructing the flow so d.model is non-nil.","Ensure the relevant API key env var (e.g. OPENAI_API_KEY or the provider's equivalent) is set in the runtime environment.","If invoking LLM steps directly in tests, attach flow deps with a model to the context instead of passing a bare context.Background().","Replace the LLM step with a plain Run function if no model is intended for this flow."],"exampleFix":"// before\nf := flow.New(flow.Steps(flow.LLM(\"Summarize: {{.Data}}\")))\n\n// after\nf := flow.New(\n  flow.Provider(\"openai\"),\n  flow.APIKey(os.Getenv(\"OPENAI_API_KEY\")),\n  flow.Steps(flow.LLM(\"Summarize: {{.Data}}\")),\n)","handlingStrategy":"validation","validationCode":"if flowDepsFrom(ctx) == nil || flowDepsFrom(ctx).model == nil {\n    return errors.New(\"flow model not configured: set Provider/APIKey before using LLM steps\")\n}","typeGuard":"func hasFlowModel(ctx context.Context) bool {\n    d := depsFrom(ctx)\n    return d != nil && d.model != nil\n}","tryCatchPattern":"state, err := step(ctx, in)\nif err != nil {\n    if strings.Contains(err.Error(), \"requires a flow model\") {\n        // configure model and retry, or skip LLM step\n    }\n    return err\n}","preventionTips":["Always set Provider and APIKey options when a flow contains LLM steps","Source provider API keys from env at startup and fail fast if unset","In tests, build a helper that attaches deps with a model to the test context","Cover each LLM step in an integration test so missing config surfaces in CI"],"tags":["go","llm","configuration","flow"],"backgroundTag":"missing-model-configuration","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}