temporalio/temporal · error
nexus service %s is already registered
Error message
nexus service %s is already registered
What it means
registerNexusService rejects registering a nexus.Service whose Name already exists in r.nexusServices. Nexus service names must be unique in the registry because they route inbound Nexus calls to handlers.
Source
Thrown at chasm/registry.go:370
return nil
}
func (r *Registry) warnUnmanagedFields(fqn string, rc *RegistrableComponent) {
var unmanagedFields []string
for f := range unmanagedFieldsOf(rc.goType) {
unmanagedFields = append(unmanagedFields, fmt.Sprintf("%s %s", f.name, f.typ))
}
if len(unmanagedFields) > 0 {
r.logger.Info(fmt.Sprintf(
"Warning: CHASM component %s declares state fields that won't be managed by CHASM:\n\t%s",
fqn,
strings.Join(unmanagedFields, "\n\t")))
}
}
func (r *Registry) registerNexusService(svc *nexus.Service) error {
if _, ok := r.nexusServices[svc.Name]; ok {
return fmt.Errorf("nexus service %s is already registered", svc.Name)
}
r.nexusServices[svc.Name] = svc
return nil
}
// NexusServices returns all registered Nexus services.
func (r *Registry) NexusServices() map[string]*nexus.Service {
// Return a copy to prevent external modification
services := make(map[string]*nexus.Service, len(r.nexusServices))
maps.Copy(services, r.nexusServices)
return services
}
func (r *Registry) componentContextValue(key any) any {
if v, ok := r.rcContextValues[key]; ok {
return v.v
}
return nilView on GitHub (pinned to bde624efd1)
Solutions
- Remove the duplicate registration so each nexus service name is registered once.
- Give the second service a unique name.
- If both packages need the same service, export one registration and import it instead of duplicating.
Example fix
// before
reg.RegisterNexusService(nexus.NewService("billing", ...))
reg.RegisterNexusService(nexus.NewService("billing", ...))
// after
reg.RegisterNexusService(nexus.NewService("billing", ...)) Defensive patterns
Strategy: validation
Validate before calling
if registeredNexusNames[svc.Name] {
return fmt.Errorf("nexus service %s already registered", svc.Name)
} Try / catch
if err := registerNexusService(reg, svc); err != nil && strings.Contains(err.Error(), "is already registered") {
return nil // idempotent bootstrap
} Prevention
- Register each nexus service once from a single bootstrap path.
- Keep a canonical list of service names and assert uniqueness at startup.
- Avoid registering nexus services inside library init() functions.
When it happens
Trigger: Registering the same nexus service name twice via chasm.Register; two packages' init() both registering a service with the same name; registering two distinct nexus.Service instances that share a name.
Common situations: Shared infrastructure package and app bootstrap both registering the same service name; renaming a service but leaving the old registration in place; multi-tenant setups reusing a name across libraries loaded into one binary.
Related errors
- component type %s is already registered
- task %s is already registered
- task type %s is already registered
- ErrDuplicateRegistration
- component type %s must be struct or pointer to struct
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/57baceb17bc4a7f5.
Report an issue: GitHub.