larksuite/cli · error

preparation strategy %q is not registered

Error message

preparation strategy %q is not registered

What it means

Registry.get in internal/event/application/consume/strategy.go reports that a PreparationStrategy referenced by a catalog.StrategyRef is absent from the registry map. The consume pipeline (Decide/Execute) or audit rendering asked for a strategy this build does not register. It is a lookup failure over the set installed by DefaultRegistry.

Source

Thrown at internal/event/application/consume/strategy.go:63

	Apply(ctx context.Context, d PreparationDecision, in PreparedConsume, ec ExecutionContext) (Cleanup, error)
}

// Registry holds the executable strategies and doubles as the catalog's
// StrategySet, so the compiler validates references against exactly the set
// that will execute.
type Registry struct {
	strategies map[catalog.StrategyRef]PreparationStrategy
}

func (r *Registry) Has(ref catalog.StrategyRef) bool {
	_, ok := r.strategies[ref]
	return ok
}

func (r *Registry) get(ref catalog.StrategyRef) (PreparationStrategy, error) {
	s, ok := r.strategies[ref]
	if !ok {
		return nil, fmt.Errorf("preparation strategy %q is not registered", ref)
	}
	return s, nil
}

// DefaultRegistry returns the strategies this build ships: no preparation,
// and the wrapper over a declaration's PreConsume hook.
func DefaultRegistry() *Registry {
	return &Registry{strategies: map[catalog.StrategyRef]PreparationStrategy{
		catalog.StrategyNone:             noneStrategy{},
		catalog.StrategyLegacyPreConsume: legacyPreConsumeStrategy{},
	}}
}

// noneStrategy: the key needs nothing before consuming.
type noneStrategy struct{}

func (noneStrategy) Decide(context.Context, PreparedConsume) (PreparationDecision, error) {
	return PreparationDecision{Strategy: catalog.StrategyNone}, nil

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Print the ref and compare against the keys registered in DefaultRegistry; fix the declaration's strategy name to a registered one
  2. If using a custom Registry, register the missing PreparationStrategy before Compile/Decide runs
  3. Rebuild/sync so the catalog metadata matches the binary's shipped strategies
  4. Add a startup validation step that resolves all declaration strategy refs so failures surface early

Example fix

// before
reg := consume.NewRegistry() // custom, missing strategies
// after
reg := consume.DefaultRegistry()
reg.Register(myCustomStrategy) // ensure refs used by declarations exist
Defensive patterns

Strategy: validation

Validate before calling

for _, ref := range declarationRefs {
    if _, err := registry.Get(ref); err != nil {
        return fmt.Errorf("declaration %s: %w", ref, err)
    }
}

Type guard

func strategyRegistered(r *consume.Registry, ref catalog.StrategyRef) bool {
    _, err := r.Get(ref)
    return err == nil
}

Try / catch

s, err := registry.Get(ref)
if err != nil {
    return fmt.Errorf("resolve preparation strategy %q: %w", ref, err)
}

Prevention

When it happens

Trigger: get() is called with a StrategyRef whose key is not in r.strategies — e.g. a declaration references a custom or renamed strategy, or the registry was constructed without DefaultRegistry's registrations and the ref expects one of them.

Common situations: Catalog metadata (from a newer or older build) names a strategy not present in the compiled binary; a typo in the strategy reference in an event declaration; building a custom Registry manually and forgetting to register a strategy the declarations use.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/4b44fbd568e8594a. Report an issue: GitHub.