{"record":{"id":"b3636188a2fab6f5","repo":"temporalio/temporal","slug":"invalid-service-q-in-service-list-v","errorCode":null,"errorMessage":"invalid service %q in service list %v","messagePattern":"invalid service %q in service list (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"temporal/server_options.go","lineNumber":87,"sourceCode":"\t}\n)\n\nfunc newServerOptions(opts []ServerOption) *serverOptions {\n\tso := &serverOptions{\n\t\t// Set defaults here.\n\t\tpersistenceServiceResolver: resolver.NewNoopResolver(),\n\t}\n\tfor _, opt := range opts {\n\t\topt.apply(so)\n\t}\n\n\treturn so\n}\n\nfunc (so *serverOptions) loadAndValidate() error {\n\tfor serviceName := range so.serviceNames {\n\t\tif !slices.Contains(Services, string(serviceName)) {\n\t\t\treturn fmt.Errorf(\"invalid service %q in service list %v\", serviceName, so.serviceNames)\n\t\t}\n\t}\n\n\tif so.config == nil {\n\t\terr := so.loadConfig()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to load config: %w\", err)\n\t\t}\n\t}\n\n\terr := so.validateConfig()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"config validation error: %w\", err)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/temporal/server_options.go#L69-L105","documentation":"Returned by serverOptions.loadAndValidate when a service name supplied via WithServices (or the services list) is not one of the known Temporal services: frontend, internal-frontend, history, matching, worker. It is a fast-fail configuration validation so an unknown/typo'd service name aborts before any config load or service startup.","triggerScenarios":"Passing temporal.WithServices(\"frontend1\"), a typo like \"front-end\" or \"workers\", or a service name valid in an older/newer Temporal version (e.g. \"internal-frontend\" on a build that doesn't define it) to temporal.NewServer, or listing an invalid service in the services config.","commonSituations":"Typos or wrong casing in WithServices arguments; copying service names from another product/version; enabling internal-frontend when the build/config doesn't support it; programmatic service selection built from a config file that contains an unexpected value.","solutions":["Use one of the exact supported names: frontend, internal-frontend, history, matching, worker (see temporal.Services in temporal/server.go)","Fix typos and casing — the check is a plain string comparison against the Services slice","If you intended internal-frontend, confirm your Temporal build/version supports it before including it","If the list comes from a config file, validate its contents against the supported set before constructing the server","If you need a custom service, that is not supported by this option set — remove the entry and rely on the standard services"],"exampleFix":"// before\nsrv, err := temporal.NewServer(\n\ttemporal.WithServices(\"front-end\", \"history\", \"matching\", \"worker\"),\n)\n// invalid service \"front-end\" in service list [front-end history matching worker]\n\n// after\nsrv, err := temporal.NewServer(\n\ttemporal.WithServices(temporal.FrontendService, \"history\", \"matching\", \"worker\"),\n)","handlingStrategy":"validation","validationCode":"func validServices(names []string) error {\n\tfor _, n := range names {\n\t\tswitch n {\n\t\tcase \"frontend\", \"internal-frontend\", \"history\", \"matching\", \"worker\":\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"invalid service %q; supported: frontend, internal-frontend, history, matching, worker\", n)\n\t\t}\n\t}\n\treturn nil\n}\n// call validServices(myServices) before temporal.NewServer(temporal.WithServices(myServices...))","typeGuard":null,"tryCatchPattern":"srv, err := temporal.NewServer(temporal.WithServices(names...))\nif err != nil && strings.Contains(err.Error(), \"invalid service\") {\n\tlog.Fatalf(\"fix service list: %v\", err)\n}","preventionTips":["Copy service names only from the temporal.Services / DefaultServices constants in temporal/server.go","Centralize the service list in one validated config value","Lint/validate service names in CI before deployment","Watch for renames across Temporal versions when upgrading","Never free-form service names from user input into WithServices"],"tags":["config","validation","startup","services"],"backgroundTag":"invalid-service-name","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}