{"record":{"id":"a08d2765a2e0d44c","repo":"temporalio/temporal","slug":"component-type-s-must-be-and-interface-or-struct","errorCode":null,"errorMessage":"component type %s must be and interface or struct that implements Component interface","messagePattern":"component type (.+?) must be and interface or struct that implements Component interface","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"chasm/registry.go","lineNumber":325,"sourceCode":"\t\treturn fmt.Errorf(\"task %s is already registered\", fqn)\n\t}\n\n\tif existingTask, ok := r.rtByID[id]; ok {\n\t\treturn fmt.Errorf(\"task type ID %d collision between %s and %s\", id, fqn, existingTask.fqType())\n\t}\n\n\tif !(rt.goType.Kind() == reflect.Struct ||\n\t\t(rt.goType.Kind() == reflect.Pointer && rt.goType.Elem().Kind() == reflect.Struct)) {\n\t\treturn fmt.Errorf(\"task type %s must be struct or pointer to struct\", rt.goType.String())\n\t}\n\tif _, ok := r.rtByGoType[rt.goType]; ok {\n\t\treturn fmt.Errorf(\"task type %s is already registered\", rt.goType.String())\n\t}\n\tif !(rt.componentGoType.Kind() == reflect.Interface ||\n\t\t(rt.componentGoType.Kind() == reflect.Struct ||\n\t\t\t(rt.componentGoType.Kind() == reflect.Pointer && rt.componentGoType.Elem().Kind() == reflect.Struct)) &&\n\t\t\trt.componentGoType.AssignableTo(reflect.TypeFor[Component]())) {\n\t\treturn fmt.Errorf(\"component type %s must be and interface or struct that implements Component interface\", rt.componentGoType.String())\n\t}\n\n\tr.rtByFqn[fqn] = rt\n\tr.rtByID[id] = rt\n\tr.rtByGoType[rt.goType] = rt\n\treturn nil\n}\n\nfunc (r *Registry) validateName(n string) error {\n\tif n == \"\" {\n\t\treturn errors.New(\"name must not be empty\")\n\t}\n\tif !nameValidator.MatchString(n) {\n\t\treturn fmt.Errorf(\"name %s is invalid. name must follow golang identifier rules: %s\", n, nameValidator.String())\n\t}\n\treturn nil\n}\n","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/chasm/registry.go#L307-L343","documentation":"registerTask validates that the task's associated component type is either an interface, or a struct/pointer-to-struct that is AssignableTo the Component interface. A task must declare which component it operates on; if the declared type doesn't satisfy Component, the task cannot be dispatched. This is typically a wrong type parameter in RegisterTask.","triggerScenarios":"Passing a component type parameter that does not implement chasm.Component (missing required methods, or a totally unrelated struct/pointer type) to chasm.RegisterTask.","commonSituations":"Component interface evolved and the type no longer satisfies it after an upgrade; passing a DTO struct instead of the component; mixing up type-parameter order in RegisterTask[Task, Component].","solutions":["Make the component type parameter a type that implements chasm.Component (verify required methods exist).","Swap type parameters if Task and Component were reversed at the call site.","Add a compile-time assertion `var _ chasm.Component = (*MyComponent)(nil)` to catch drift early."],"exampleFix":"// before\nvar _ chasm.Component = (*OrderDTO)(nil) // fails\nchasm.RegisterTask[OrderTask, OrderDTO](reg, \"order_task\", opts)\n// after\nvar _ chasm.Component = (*OrderImpl)(nil)\nchasm.RegisterTask[OrderTask, OrderImpl](reg, \"order_task\", opts)","handlingStrategy":"type-guard","validationCode":"var _ chasm.Component = (*MyComponent)(nil) // compile-time guard before registration","typeGuard":"func implementsComponent(t reflect.Type) bool {\n\treturn t != nil && t.AssignableTo(reflect.TypeFor[chasm.Component]())\n}","tryCatchPattern":null,"preventionTips":["Add compile-time assertions (var _ chasm.Component = (*T)(nil)) next to every component struct.","Keep type-parameter order consistent: RegisterTask[TaskType, ComponentType].","After chasm upgrades, build first — interface method changes surface at compile time."],"tags":["chasm","registry","type-mismatch","task-registration"],"backgroundTag":"type-does-not-implement-interface","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}