{"record":{"id":"de52dc2d030fe8d8","repo":"apache/beam","slug":"unknown-shutdownmode-v","errorCode":null,"errorMessage":"unknown ShutdownMode: %v","messagePattern":"unknown ShutdownMode: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/harness/init/init.go","lineNumber":138,"sourceCode":"\t\t\texperiments = strings.Split(e, \",\")\n\t\t}\n\t\t// TODO(zechenj18) 2023-12-07: Remove once the data sampling URN is properly sent in via the capabilities\n\t\tif slices.Contains(experiments, \"enable_data_sampling\") {\n\t\t\trunnerCapabilities = append(runnerCapabilities, graphx.URNDataSampling)\n\t\t}\n\t}\n\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tfmt.Fprintf(os.Stderr, \"Worker panic: %v\\n\", r)\n\t\t\tdebug.PrintStack()\n\t\t\tswitch ShutdownMode {\n\t\t\tcase Terminate:\n\t\t\t\tos.Exit(2)\n\t\t\tcase Return:\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\tpanic(fmt.Sprintf(\"unknown ShutdownMode: %v\", ShutdownMode))\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Since Init() is hijacking main, it's appropriate to do as main\n\t// does, and establish the background context here.\n\t// We produce a cancelFn here so runs in Loopback mode and similar can clean up\n\t// any leftover goroutines.\n\tctx, cancelFn := context.WithCancel(context.Background())\n\tdefer cancelFn()\n\tctx = grpcx.WriteWorkerID(ctx, *id)\n\tmemLimit := memoryLimit()\n\tif err := syscallx.SetProcessMemoryCeiling(memLimit, memLimit); err != nil && err != syscallx.ErrUnsupported {\n\t\tfmt.Println(\"Error Setting Rlimit \", err)\n\t}\n\n\toptions := harness.Options{\n\t\tStatusEndpoint:     statusEndpoint,","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/harness/init/init.go#L120-L156","documentation":"beam.Init() takes over main for Beam workers and installs an exit hook that decides whether the process terminates hard (os.Exit) or returns control. Only ShutdownMode Terminate and Return are defined; any other value is a programming error, so the code panics with the offending value.","triggerScenarios":"Assigning any value to the harness init.ShutdownMode package variable other than init.Terminate or init.Return before/while the deferred exit hook runs in the path guarded by the harness Main.","commonSituations":"Custom worker code setting ShutdownMode to an out-of-range integer or an unexported/foreign type; copy-paste code importing the wrong ShutdownMode constant; concurrent code mutating ShutdownMode mid-run.","solutions":["Set ShutdownMode only to init.Terminate or init.Return.","Remove any custom assignment if you don't need to change shutdown behavior; keep the default.","Audit for concurrent writes to ShutdownMode; make the assignment once at startup."],"exampleFix":"// before\ninit.ShutdownMode = init.ShutdownMode(3)\n// after\ninit.ShutdownMode = init.Return // or init.Terminate","handlingStrategy":"validation","validationCode":"if init.ShutdownMode != init.Terminate && init.ShutdownMode != init.Return {\n    panic(\"ShutdownMode must be init.Terminate or init.Return\")\n}","typeGuard":null,"tryCatchPattern":"defer func() { if r := recover(); r != nil { log.Fatalf(\"shutdown mode error: %v\", r) } }()","preventionTips":["Only assign the two exported constants to ShutdownMode","Never read ShutdownMode values from unvalidated config","Set ShutdownMode once, early, and treat it as immutable"],"tags":["go","apache-beam","harness","panic"],"backgroundTag":"invalid-enum-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}