micro/go-micro · error

verify grade attempt %d: %w

Error message

verify grade attempt %d: %w

What it means

This error wraps an error returned by the grader function inside flow.Verify, annotated with the attempt number. Unlike a body error, a grader error aborts the whole verification (no retry on the next attempt), returning the last good State. The %w wrapping preserves the original grader failure.

Source

Thrown at flow/verify.go:95

		for attempt := 1; attempt <= o.MaxAttempts; attempt++ {
			if err := ctx.Err(); err != nil {
				return last, err
			}
			if feedback != "" {
				var err error
				cur, err = stateWithField(cur, o.FeedbackField, feedback)
				if err != nil {
					return last, err
				}
			}
			out, err := body(ctx, cur)
			if err != nil {
				return last, fmt.Errorf("verify attempt %d: %w", attempt, err)
			}
			last = out
			pass, fb, err := grader(ctx, out)
			if err != nil {
				return last, fmt.Errorf("verify grade attempt %d: %w", attempt, err)
			}
			if pass {
				return stateWithVerification(out, true, fb, attempt)
			}
			feedback = fb
			cur = in
			if attempt < o.MaxAttempts && o.Backoff > 0 {
				select {
				case <-time.After(o.Backoff):
				case <-ctx.Done():
					return last, ctx.Err()
				}
			}
		}
		return stateWithVerification(last, false, feedback, o.MaxAttempts)
	}
}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Unwrap with errors.Is/As to find the grader's root cause (often an LLM API error).
  2. For LLMGrader, confirm the flow model is configured (Provider/APIKey) and the API is reachable.
  3. Make custom graders defensive: never return an error for gradable-but-failing output; return (false, feedback, nil) instead, reserving errors for true failures.

Example fix

// before
func myGrader(ctx context.Context, out flow.State) (bool, string, error) {
    score, err := strconv.Atoi(out.String()) // errors on normal output
    ...
}
// after
func myGrader(ctx context.Context, out flow.State) (bool, string, error) {
    score, err := strconv.Atoi(strings.TrimSpace(out.String()))
    if err != nil {
        return false, "output was not a numeric score", nil
    }
    return score >= 7, "", nil
}
Defensive patterns

Strategy: try-catch

Try / catch

out, err := step(ctx, in)
if err != nil {
    if cause := errors.Unwrap(err); cause != nil && isLLMError(cause) {
        // check model config / quota, then re-run with backoff
    }
    return out, err
}

Prevention

When it happens

Trigger: Any Verify run where grader(ctx, out) returns a non-nil error, producing 'verify grade attempt N: <cause>'.

Common situations: LLMGrader's model call fails (missing API key, quota, network); a custom grader hits a nil map/index; the grader mis-parses an unexpected State shape.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/acdf3b471b0b6125. Report an issue: GitHub.