micro/go-micro · error
flow: UntilLLM requires a flow model (set Provider/APIKey)
Error message
flow: UntilLLM requires a flow model (set Provider/APIKey)
What it means
The UntilLLM loop's supervised stop check (askDone, via loopDone) needs the flow model to judge whether the goal is met, but no model was found in the context dependencies. The library tells you exactly which flow settings are missing: Provider and/or APIKey.
Source
Thrown at flow/loop.go:128
func loopDone(ctx context.Context, o LoopOptions, state State, iter int) (bool, error) {
if o.Until != nil {
done, err := o.Until(ctx, state, iter)
if err != nil || done {
return done, err
}
}
if o.UntilLLM != "" {
return askDone(ctx, o.UntilLLM, state)
}
return false, nil
}
// askDone asks the flow model whether the goal is met given the current
// state, and returns true on an affirmative reply — the supervised stop check.
func askDone(ctx context.Context, question string, state State) (bool, error) {
d := depsFrom(ctx)
if d == nil || d.model == nil {
return false, fmt.Errorf("flow: UntilLLM requires a flow model (set Provider/APIKey)")
}
prompt := fmt.Sprintf("%s\n\nLatest result:\n%s\n\nAnswer with only \"yes\" or \"no\".", question, state.String())
resp, err := d.model.Generate(ctx, &ai.Request{Prompt: prompt})
if err != nil {
return false, err
}
reply := resp.Answer
if reply == "" {
reply = resp.Reply
}
return isAffirmative(reply), nil
}
// isAffirmative reports whether a model reply reads as "yes/done".
func isAffirmative(s string) bool {
s = strings.ToLower(strings.TrimSpace(s))
for _, p := range []string{"yes", "done", "true", "complete", "finished"} {
if strings.HasPrefix(s, p) {View on GitHub (pinned to 24529f1404)
Solutions
- Set Provider and APIKey in the flow options so the flow model is initialized.
- If running steps manually, inject the model deps into the context as UntilLLM expects.
- Verify ai.New returned a non-nil model (see error 304) before using UntilLLM.
- Use a non-LLM stop condition (max iterations or a done predicate) when no model is available.
Example fix
// before
f, _ := flow.New("myflow") // no provider
f.UntilLLM("Is the goal met?")
// after
f, _ := flow.New("myflow", flow.Provider("openai"), flow.APIKey(os.Getenv("OPENAI_API_KEY")))
f.UntilLLM("Is the goal met?") Defensive patterns
Strategy: validation
Validate before calling
if cfg.Provider == "" || cfg.APIKey == "" {
return errors.New("UntilLLM requires flow Provider and APIKey to be set")
} Type guard
func untilLLMReady(ctx context.Context) bool {
d := depsFrom(ctx)
return d != nil && d.model != nil
} Try / catch
done, err := loopDone(ctx, opts, state, iter)
if err != nil && strings.Contains(err.Error(), "requires a flow model") {
// fall back to a non-LLM stop condition
done = iter >= opts.Max
} Prevention
- Validate Provider/APIKey at flow construction, before any UntilLLM step runs.
- Run UntilLLM loops only through the normal flow execution path that injects model deps.
- Provide a fallback done-predicate for environments without model credentials.
When it happens
Trigger: Running a UntilLLM loop when the context carries no deps or deps.model is nil — i.e. the flow was created without Provider/APIKey, or the model wasn't injected into the context before the step executed.
Common situations: Using UntilLLM in a flow constructed with an empty Provider config; running steps outside the normal flow execution path so the context lacks model deps; a nil model caused by an unknown provider (related to error 304).
Related errors
- LLM step requires a flow model (set Provider/APIKey)
- flow: LLMGrader requires a flow model (set Provider/APIKey)
- flow: LLMOptimizer requires a model
- unknown provider: %s
- flow %s has no checkpoint configured
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/6caa2a858786cfdb.
Report an issue: GitHub.