micro/go-micro · error

flow: step %d has an empty name

Error message

flow: step %d has an empty name

What it means

This error comes from flow.validateSteps, which iterates every step in a flow definition and rejects any step whose Name field is an empty string. The library requires named steps because step names are used for addressing, deduplication, and references between steps. It fires before the flow ever runs, at construction/validation time.

Source

Thrown at flow/steps.go:725

	}
}

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
}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Set a unique non-empty Name on every Step in the slice passed to the flow builder.
  2. If steps are loaded from config, validate the config before constructing the flow and report which step index is missing a name.
  3. Add a helper constructor that requires a name parameter so a Step cannot be built without one.

Example fix

// before
steps := []flow.Step{{Action: myAction}}
// after
steps := []flow.Step{{Name: "my-step", Action: myAction}}
Defensive patterns

Strategy: validation

Validate before calling

for i, s := range steps {
    if s.Name == "" {
        return fmt.Errorf("step %d: name must be non-empty", i)
    }
}

Type guard

func hasValidNames(steps []flow.Step) bool {
    for _, s := range steps {
        if s.Name == "" {
            return false
        }
    }
    return true
}

Prevention

When it happens

Trigger: Calling any flow-building/validation API that reaches validateSteps while a Step literal in the []Step slice has Name == "", e.g. flow steps declared as {Action: ...} without setting Name.

Common situations: Constructing steps programmatically and forgetting to set Name; building steps from config/YAML where a 'name:' key was omitted or empty; a step factory returning a zero-value Step.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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