{"record":{"id":"6d2bc8d94a01121a","repo":"micro/go-micro","slug":"verify-attempt-d-w","errorCode":null,"errorMessage":"verify attempt %d: %w","messagePattern":"verify attempt (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"flow/verify.go","lineNumber":90,"sourceCode":"\t\t\treturn in, fmt.Errorf(\"flow: Verify requires a grader\")\n\t\t}\n\t\tcur := in\n\t\tlast := in\n\t\tfeedback := \"\"\n\t\tfor attempt := 1; attempt <= o.MaxAttempts; attempt++ {\n\t\t\tif err := ctx.Err(); err != nil {\n\t\t\t\treturn last, err\n\t\t\t}\n\t\t\tif feedback != \"\" {\n\t\t\t\tvar err error\n\t\t\t\tcur, err = stateWithField(cur, o.FeedbackField, feedback)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn last, err\n\t\t\t\t}\n\t\t\t}\n\t\t\tout, err := body(ctx, cur)\n\t\t\tif err != nil {\n\t\t\t\treturn last, fmt.Errorf(\"verify attempt %d: %w\", attempt, err)\n\t\t\t}\n\t\t\tlast = out\n\t\t\tpass, fb, err := grader(ctx, out)\n\t\t\tif err != nil {\n\t\t\t\treturn last, fmt.Errorf(\"verify grade attempt %d: %w\", attempt, err)\n\t\t\t}\n\t\t\tif pass {\n\t\t\t\treturn stateWithVerification(out, true, fb, attempt)\n\t\t\t}\n\t\t\tfeedback = fb\n\t\t\tcur = in\n\t\t\tif attempt < o.MaxAttempts && o.Backoff > 0 {\n\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}","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/flow/verify.go#L72-L108","documentation":"This error wraps an error returned by the body step inside the flow.Verify retry loop, annotated with the 1-based attempt number. When the body fails, Verify immediately returns the last successful State wrapped with this message — it does NOT retry on body errors, only on failed grades. The %w wrapping preserves the underlying cause for errors.Is/As.","triggerScenarios":"Any invocation of a Verify-wrapped step where body(ctx, cur) returns a non-nil error on attempt N; message reads 'verify attempt N: <underlying error>'.","commonSituations":"The body step calls an LLM/API that fails (rate limit, timeout, invalid response); the body panics-free but returns an error on first or later attempts; transient network failures during attempt 1.","solutions":["Inspect the wrapped cause with errors.Unwrap / errors.Is to find the real body failure.","If the failure is transient and retrying is desired, add retry logic inside the body step itself, since Verify does not retry body errors.","Check that inputs to the body (cur State) are valid; a malformed State will fail every attempt."],"exampleFix":"// before\nout, err := body(ctx, cur)\n// after (retry transient body errors inside the body)\nout, err := retryIfTransient(ctx, cur) // wrap flaky calls with backoff","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"out, err := step(ctx, in)\nif err != nil {\n    var cause error\n    if errors.As(err, &cause) || errors.Unwrap(err) != nil {\n        cause = errors.Unwrap(err)\n    }\n    if isTransient(cause) {\n        // retry inside the body; Verify does not retry body errors\n        out, err = step(ctx, in)\n    }\n    return out, err\n}","preventionTips":["Wrap flaky I/O inside the body step with its own retry/backoff.","Match on the wrapped cause with errors.Is/As, not the message string.","Validate State inputs to the body to avoid deterministic failures."],"tags":["go","flow","verify","retry","error-wrapping"],"backgroundTag":"wrapped-step-error","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}