{"record":{"id":"b19199c2de2e1c1a","repo":"temporalio/temporal","slug":"invalid-operation-token","errorCode":null,"errorMessage":"invalid operation token","messagePattern":"invalid operation token","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"chasm/lib/nexusoperation/task_handler_helpers.go","lineNumber":28,"sourceCode":"\t\"time\"\n\n\t\"github.com/nexus-rpc/sdk-go/nexus\"\n\tcommonpb \"go.temporal.io/api/common/v1\"\n\tenumspb \"go.temporal.io/api/enums/v1\"\n\tfailurepb \"go.temporal.io/api/failure/v1\"\n\t\"go.temporal.io/api/serviceerror\"\n\tpersistencespb \"go.temporal.io/server/api/persistence/v1\"\n\ttokenspb \"go.temporal.io/server/api/token/v1\"\n\t\"go.temporal.io/server/common\"\n\t\"go.temporal.io/server/common/namespace\"\n\tcommonnexus \"go.temporal.io/server/common/nexus\"\n\t\"go.temporal.io/server/common/nexus/nexusrpc\"\n\tqueueserrors \"go.temporal.io/server/service/history/queues/errors\"\n)\n\nvar (\n\tErrResponseBodyTooLarge  = errors.New(\"http: response body too large\")\n\tErrInvalidOperationToken = errors.New(\"invalid operation token\")\n\terrRequestTimedOut       = errors.New(\"request timed out\")\n\terrOpProcessorFailed     = errors.New(\"nexus operation processor failed\")\n)\n\nconst maxDuration = time.Duration(1<<63 - 1)\n\ntype operationTimeoutBelowMinError struct {\n\ttimeoutType enumspb.TimeoutType\n}\n\nfunc (o *operationTimeoutBelowMinError) Error() string {\n\treturn fmt.Sprintf(\"not enough time to execute another request before %s timeout\", o.timeoutType.String())\n}\n\nfunc isDestinationDown(err error) bool {\n\tif _, ok := errors.AsType[serviceerror.ServiceError](err); ok {\n\t\treturn false\n\t}","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/chasm/lib/nexusoperation/task_handler_helpers.go#L10-L46","documentation":"validateCAs iterates a list of CA entries (inline PEM data or file paths) and rejects any entry whose TrimSpace is empty. This is a guard against silently building an empty or malformed CA pool from blank list items, which would cause hard-to-debug TLS verification failures later.","triggerScenarios":"Any validateServerTLS or validateClientTLS path where ClientCAData/ClientCAFiles/RootCAData/RootCAFiles contains \"\" or a whitespace-only string.","commonSituations":"Empty YAML list items, env-var substitution expanding to nothing, unfilled template placeholders, secret mount not present so data is blank, copy-paste trailing empty element.","solutions":["Delete the empty entry from the CA list in your config.","Fix whatever produced the blank value (unset env var, missing secret, bad template).","If a CA is optional, omit the entry entirely instead of passing \"\".","Pre-validate the rendered config with a script that trims and drops blank CA entries before startup."],"exampleFix":"// before\nRootCAData: [\"-----BEGIN CERTIFICATE-----...\", \"  \"]\n// after\nRootCAData: [\"-----BEGIN CERTIFICATE-----...\"]","handlingStrategy":"validation","validationCode":"func hasEmptyCA(cas []string) bool {\n\tfor _, ca := range cas {\n\t\tif strings.TrimSpace(ca) == \"\" {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Sanitize CA lists (trim/drop blanks) right after config load, before validation.","Treat empty CA entries as config corruption, not an optional value.","Test config rendering in CI with the same templates used in production."],"tags":["tls","config-validation","ca-certificates"],"backgroundTag":"tls-config-conflict","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}