micro/go-micro · error

flow: duplicate step name %q

Error message

flow: duplicate step name %q

What it means

flow.validateSteps maintains a 'seen' set and rejects a flow whose steps contain two steps with the same Name. Duplicate names make step references ambiguous, so the library refuses to build the flow. Raised at validation time, before execution.

Source

Thrown at flow/steps.go:728

func (f *Flow) save(ctx context.Context, run Run) error {
	if f.checkpoint == nil {
		return nil
	}
	if err := f.checkpoint.Save(ctx, run); err != nil {
		f.log.Logf(logger.ErrorLevel, "Flow %s checkpoint save: %v", f.name, err)
		return fmt.Errorf("flow %s checkpoint save: %w", f.name, err)
	}
	return nil
}

func validateSteps(steps []Step) error {
	seen := make(map[string]struct{}, len(steps))
	for i, step := range steps {
		if step.Name == "" {
			return fmt.Errorf("flow: step %d has an empty name", i)
		}
		if _, ok := seen[step.Name]; ok {
			return fmt.Errorf("flow: duplicate step name %q", step.Name)
		}
		seen[step.Name] = struct{}{}
	}
	return nil
}

func stepIndex(steps []Step, name string) int {
	for i, s := range steps {
		if s.Name == name {
			return i
		}
	}
	return -1
}

func resultFromRun(trigger string, run Run) Result {
	r := Result{
		FlowName:  run.Flow,

View on GitHub (pinned to 24529f1404)

Solutions

  1. Rename one of the duplicate steps so all step names are unique.
  2. Pre-check names client-side with a map before constructing the flow to get a clearer failure message.
  3. If duplication is intentional (repeated logic), refactor into a named helper/loop instead of duplicating a step name.

Example fix

// before
steps := []flow.Step{{Name: "fetch"}, {Name: "fetch"}}
// after
steps := []flow.Step{{Name: "fetch"}, {Name: "fetch-retry"}}
Defensive patterns

Strategy: validation

Validate before calling

seen := make(map[string]struct{}, len(steps))
for _, s := range steps {
    if _, dup := seen[s.Name]; dup {
        return fmt.Errorf("duplicate step name %q", s.Name)
    }
    seen[s.Name] = struct{}{}
}

Prevention

When it happens

Trigger: Passing a []Step to the flow builder where two entries have identical Name values; the error message includes the duplicated name in %q.

Common situations: Copy-pasting a step definition and forgetting to rename it; generating steps in a loop with a constant name; merging step lists from multiple sources where names collide.

Related errors


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