{"record":{"id":"281a0a73fb53c14f","repo":"apache/beam","slug":"num-workers-d-cannot-be-negative","errorCode":null,"errorMessage":"num_workers (%d) cannot be negative","messagePattern":"num_workers \\((.+?)\\) cannot be negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/runners/dataflow/dataflowlib/job.go","lineNumber":439,"sourceCode":"\t\treturn errors.New(\"experiment worker_region and option workerRegion are mutually exclusive\")\n\t}\n\tif hasExperimentWorkerRegion && opts.WorkerZone != \"\" {\n\t\treturn errors.New(\"experiment worker_region and option workerZone are mutually exclusive\")\n\t}\n\tif hasExperimentWorkerRegion && opts.Zone != \"\" {\n\t\treturn errors.New(\"experiment worker_region and option Zone are mutually exclusive\")\n\t}\n\n\tif opts.Zone != \"\" {\n\t\tlog.Warn(ctx, \"Option --zone is deprecated. Please use --workerZone instead.\")\n\t\topts.WorkerZone = opts.Zone\n\t\topts.Zone = \"\"\n\t}\n\n\tnumWorkers := opts.NumWorkers\n\tmaxNumWorkers := opts.MaxNumWorkers\n\tif numWorkers < 0 {\n\t\treturn fmt.Errorf(\"num_workers (%d) cannot be negative\", numWorkers)\n\t}\n\tif maxNumWorkers < 0 {\n\t\treturn fmt.Errorf(\"max_num_workers (%d) cannot be negative\", maxNumWorkers)\n\t}\n\tif numWorkers > 0 && maxNumWorkers > 0 && numWorkers > maxNumWorkers {\n\t\treturn fmt.Errorf(\"num_workers (%d) cannot exceed max_num_workers (%d)\", numWorkers, maxNumWorkers)\n\t}\n\treturn nil\n}\n","sourceCodeStart":421,"sourceCodeEnd":449,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/runners/dataflow/dataflowlib/job.go#L421-L449","documentation":"validateWorkerSettings checks Dataflow pipeline options before job translation. If opts.NumWorkers is negative, the Dataflow job request would be invalid, so translation fails early with 'num_workers (%d) cannot be negative'. This is a straightforward config sanity check.","triggerScenarios":"Submitting a Dataflow job where PipelineOptions.NumWorkers was computed from user input/flags/env and ended up negative — e.g. a flag parsed without bounds, a subtraction that underflowed, or a default set to -1 to mean 'unset'.","commonSituations":"CLI flags like --num-workers passed a negative value; templating code that does baseWorkers - reservedWorkers going negative; using -1 as a sentinel for auto-scaling instead of omitting the field.","solutions":["Set NumWorkers to 0 to let Dataflow auto-select workers, or a positive integer; remove any -1 sentinel usage.","Validate user-supplied flags before constructing options: reject or clamp negatives at the CLI/config layer.","Fix arithmetic that derives NumWorkers (e.g. clamp with math.Max(0, computed)).","If using Go flag parsing, add a custom flag validator or check os.Args values early."],"exampleFix":"// before\nopts.NumWorkers = requested - reserved // can go negative\n\n// after\nopts.NumWorkers = requested - reserved\nif opts.NumWorkers < 0 {\n    opts.NumWorkers = 0 // let Dataflow autoscale\n}","handlingStrategy":"validation","validationCode":"if opts.NumWorkers < 0 {\n    return errors.New(\"num_workers must be >= 0 (0 lets Dataflow choose)\")\n}","typeGuard":"func numWorkersOk(n int) bool { return n >= 0 }","tryCatchPattern":null,"preventionTips":["Validate CLI flags at parse time (reject negatives for worker counts).","Use 0, not -1, as the 'unspecified/auto' sentinel.","Clamp any computed worker counts to >= 0."],"tags":["dataflow","config-validation","pipeline-options","workers"],"backgroundTag":"invalid-config-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}