{"record":{"id":"7a964e517834cc97","repo":"valyala/fasthttp","slug":"prefork-commandproducer-returned-nil-command","errorCode":null,"errorMessage":"prefork: commandproducer returned nil command","messagePattern":"prefork: commandproducer returned nil command","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"prefork/prefork.go","lineNumber":55,"sourceCode":")\n\nvar (\n\tdefaultLogger = Logger(log.New(os.Stderr, \"\", log.LstdFlags))\n\n\t// tcpListenerFile is a hook for (*net.TCPListener).File so tests can\n\t// inject failure paths without binding a real socket.\n\ttcpListenerFile = (*net.TCPListener).File\n\n\t// ErrOverRecovery is returned when child prefork process restarts exceed\n\t// the value of RecoverThreshold.\n\tErrOverRecovery = errors.New(\"prefork: exceeding the value of recoverthreshold\")\n\n\t// ErrOnlyReuseportOnWindows is returned when running on Windows without Reuseport.\n\tErrOnlyReuseportOnWindows = errors.New(\"prefork: windows only supports reuseport = true\")\n\n\t// ErrCommandProducerNilCmd is returned when a CommandProducer returns\n\t// (nil, nil) instead of a started command.\n\tErrCommandProducerNilCmd = errors.New(\"prefork: commandproducer returned nil command\")\n\n\t// ErrCommandProducerNotStarted is returned when a CommandProducer returns\n\t// an *exec.Cmd whose Process is nil (i.e. cmd.Start() was not called).\n\tErrCommandProducerNotStarted = errors.New(\"prefork: commandproducer must return a started command\")\n)\n\n// Logger is used for logging formatted messages. Its method set is intentionally\n// identical to fasthttp.Logger so that *fasthttp.Server.Logger can be assigned\n// directly.\ntype Logger interface {\n\t// Printf must have the same semantics as log.Printf.\n\tPrintf(format string, args ...any)\n}\n\n// Compile-time check that fasthttp.Logger satisfies the local Logger interface;\n// keeps the two types in sync if either side ever evolves.\nvar _ Logger = fasthttp.Logger(nil)\n","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/valyala/fasthttp/blob/c96f600972c6f4a7a30d664257b340ebe9d60124/prefork/prefork.go#L37-L73","documentation":"ErrCommandProducerNilCmd is returned when a user-supplied CommandProducer callback returns (nil, nil) instead of a started *exec.Cmd. The prefork child-process machinery needs a real command to run; a nil command with nil error is treated as a programming bug, not an operating condition.","triggerScenarios":"Passing a CommandProducer to prefork that returns nil for the command and nil for the error, e.g. `func() *exec.Cmd { return nil }`, then starting the preforker (doCommand path).","commonSituations":"Custom command producers copied from examples and stubbed out with `return nil`; conditional logic in the producer that silently falls through without returning a command or an error.","solutions":["Make the CommandProducer always return either a started *exec.Cmd or a non-nil error.","Fix fall-through branches so they never `return nil, nil`.","If no child should be spawned, don't install a CommandProducer / don't enable prefork."],"exampleFix":"// before\nproducer := func() (*exec.Cmd, error) {\n    if useCmd { return exec.Command(\"app\"), nil }\n    return nil, nil\n}\n// after\nproducer := func() (*exec.Cmd, error) {\n    if useCmd { return exec.Command(\"app\"), nil }\n    return nil, errors.New(\"no command to produce\")\n}","handlingStrategy":"validation","validationCode":"cmd, err := producer()\nif err == nil && cmd == nil {\n    return errors.New(\"commandproducer returned nil command\")\n}","typeGuard":"func validProducedCmd(cmd *exec.Cmd, err error) bool {\n    return err == nil && cmd != nil\n}","tryCatchPattern":null,"preventionTips":["Never return nil, nil from a CommandProducer — return an error instead.","Lint/review: any `return nil` in a producer should be `return nil, err`.","Write a table test covering every branch of your CommandProducer."],"tags":["prefork","commandproducer","exec"],"backgroundTag":"nil-command-from-commandproducer","analyzedSha":"c96f600972c6f4a7a30d664257b340ebe9d60124","analyzedAt":"2026-08-31T22:48:28.265Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}