{"record":{"id":"4b44fbd568e8594a","repo":"larksuite/cli","slug":"preparation-strategy-q-is-not-registered","errorCode":null,"errorMessage":"preparation strategy %q is not registered","messagePattern":"preparation strategy %q is not registered","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/event/application/consume/strategy.go","lineNumber":63,"sourceCode":"\tApply(ctx context.Context, d PreparationDecision, in PreparedConsume, ec ExecutionContext) (Cleanup, error)\n}\n\n// Registry holds the executable strategies and doubles as the catalog's\n// StrategySet, so the compiler validates references against exactly the set\n// that will execute.\ntype Registry struct {\n\tstrategies map[catalog.StrategyRef]PreparationStrategy\n}\n\nfunc (r *Registry) Has(ref catalog.StrategyRef) bool {\n\t_, ok := r.strategies[ref]\n\treturn ok\n}\n\nfunc (r *Registry) get(ref catalog.StrategyRef) (PreparationStrategy, error) {\n\ts, ok := r.strategies[ref]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"preparation strategy %q is not registered\", ref)\n\t}\n\treturn s, nil\n}\n\n// DefaultRegistry returns the strategies this build ships: no preparation,\n// and the wrapper over a declaration's PreConsume hook.\nfunc DefaultRegistry() *Registry {\n\treturn &Registry{strategies: map[catalog.StrategyRef]PreparationStrategy{\n\t\tcatalog.StrategyNone:             noneStrategy{},\n\t\tcatalog.StrategyLegacyPreConsume: legacyPreConsumeStrategy{},\n\t}}\n}\n\n// noneStrategy: the key needs nothing before consuming.\ntype noneStrategy struct{}\n\nfunc (noneStrategy) Decide(context.Context, PreparedConsume) (PreparationDecision, error) {\n\treturn PreparationDecision{Strategy: catalog.StrategyNone}, nil","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/event/application/consume/strategy.go#L45-L81","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Print the ref and compare against the keys registered in DefaultRegistry; fix the declaration's strategy name to a registered one","If using a custom Registry, register the missing PreparationStrategy before Compile/Decide runs","Rebuild/sync so the catalog metadata matches the binary's shipped strategies","Add a startup validation step that resolves all declaration strategy refs so failures surface early"],"exampleFix":"// before\nreg := consume.NewRegistry() // custom, missing strategies\n// after\nreg := consume.DefaultRegistry()\nreg.Register(myCustomStrategy) // ensure refs used by declarations exist","handlingStrategy":"validation","validationCode":"for _, ref := range declarationRefs {\n    if _, err := registry.Get(ref); err != nil {\n        return fmt.Errorf(\"declaration %s: %w\", ref, err)\n    }\n}","typeGuard":"func strategyRegistered(r *consume.Registry, ref catalog.StrategyRef) bool {\n    _, err := r.Get(ref)\n    return err == nil\n}","tryCatchPattern":"s, err := registry.Get(ref)\nif err != nil {\n    return fmt.Errorf(\"resolve preparation strategy %q: %w\", ref, err)\n}","preventionTips":["Start from consume.DefaultRegistry() rather than an empty custom registry","Validate all declaration strategy refs at startup before Decide/Execute","Keep catalog metadata and the binary in sync (same build/version)","Avoid typos: derive strategy names from constants, not string literals"],"tags":["registry","strategy","configuration","events"],"backgroundTag":"strategy-not-registered","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}