{"record":{"id":"88d30030761dd8af","repo":"temporalio/temporal","slug":"empty-operation-name","errorCode":null,"errorMessage":"empty operation name","messagePattern":"empty operation name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/nexus/nexusrpc/client.go","lineNumber":41,"sourceCode":"\t// Service name. Required.\n\tService string\n\t// A function for making HTTP requests.\n\t// Defaults to [http.DefaultClient.Do].\n\tHTTPCaller func(*http.Request) (*http.Response, error)\n\t// A [Serializer] to customize client serialization behavior.\n\t// By default the client handles JSONables, byte slices, and nil.\n\tSerializer nexus.Serializer\n\t// A [FailureConverter] to convert a [Failure] instance to and from an [error]. Defaults to\n\t// [DefaultFailureConverter].\n\tFailureConverter FailureConverter\n}\n\n// User-Agent header set on HTTP requests.\nconst userAgent = \"temporalio/server\"\n\nconst headerUserAgent = \"User-Agent\"\n\nvar errEmptyOperationName = errors.New(\"empty operation name\")\n\nvar errEmptyOperationToken = errors.New(\"empty operation token\")\n\n// UnexpectedResponseError indicates a client encountered something unexpected in the server's response.\ntype UnexpectedResponseError struct {\n\t// Error message.\n\tMessage string\n\t// Optional failure that may have been emedded in the response.\n\tFailure *nexus.Failure\n\t// Additional transport specific details.\n\t// For HTTP, this would include the HTTP response. The response body will have already been read into memory and\n\t// does not need to be closed.\n\tDetails any\n}\n\n// Error implements the error interface.\nfunc (e *UnexpectedResponseError) Error() string {\n\treturn e.Message","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/nexus/nexusrpc/client.go#L23-L59","documentation":"errEmptyOperationName is a sentinel in common/nexus/nexusrpc/client.go indicating NewOperationHandle was called with an empty operation name. An operation handle needs a valid operation identifier to form request URLs, so an empty name is rejected up front rather than producing malformed HTTP requests later.","triggerScenarios":"Calling NewOperationHandle (typically via a nexus client) with operationName == \"\", e.g. when the name comes from an unset config value, an empty workflow input, or a struct field that was never populated.","commonSituations":"Programmatic clients that derive operation names from data where the field may be absent; tests verifying failure conditions (TestNewHandleFailureConditions); serialization round-trips that drop an empty optional name field.","solutions":["Ensure the operation name is populated before calling NewOperationHandle","Check with errors.Is(err, nexusrpc.ErrEmptyOperationName) to detect this case","If the name is derived from input, fail earlier with a clear user-facing message when it is empty"],"exampleFix":"// before\nhandle, err := client.NewOperationHandle(ctx, \"\", token)\n// after\nif operationName == \"\" {\n    return nil, fmt.Errorf(\"operation name required\")\n}\nhandle, err := client.NewOperationHandle(ctx, operationName, token)","handlingStrategy":"validation","validationCode":"func checkHandleArgs(operationName, token string) error {\n    if operationName == \"\" { return errors.New(\"operation name required\") }\n    return nil\n}","typeGuard":"func hasOperationName(name string) bool { return name != \"\" }","tryCatchPattern":"handle, err := client.NewOperationHandle(ctx, opName, token)\nif errors.Is(err, nexusrpc.ErrEmptyOperationName) {\n    return fmt.Errorf(\"cannot create handle: operation name is empty\")\n}","preventionTips":["Validate operation names at the boundary where they enter your system (config, input parsing)","Use constants for operation names instead of free-form strings where possible","Test handle construction with empty inputs to catch regressions"],"tags":["nexus","client","validation"],"backgroundTag":"empty-required-field","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}