{"record":{"id":"d90b9bf608e6fdf0","repo":"hyperledger/fabric","slug":"instance-has-not-been-started","errorCode":null,"errorMessage":"instance has not been started","messagePattern":"instance has not been started","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/container/externalbuilder/instance.go","lineNumber":160,"sourceCode":"\t}\n\n\treturn ccdata.ChaincodeServerInfo(i.ChaincodeServerReleaseDir())\n}\n\nfunc (i *Instance) Start(peerConnection *ccintf.PeerConnection) error {\n\tsess, err := i.Builder.Run(i.PackageID, i.BldDir, peerConnection)\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"could not execute run\")\n\t}\n\ti.Session = sess\n\treturn nil\n}\n\n// Stop signals the process to terminate with SIGTERM. If the process doesn't\n// terminate within TermTimeout, the process is killed with SIGKILL.\nfunc (i *Instance) Stop() error {\n\tif i.Session == nil {\n\t\treturn errors.Errorf(\"instance has not been started\")\n\t}\n\n\tdone := make(chan struct{})\n\tgo func() { i.Wait(); close(done) }()\n\n\ti.Session.Signal(syscall.SIGTERM)\n\tselect {\n\tcase <-time.After(i.TermTimeout):\n\t\ti.Session.Signal(syscall.SIGKILL)\n\tcase <-done:\n\t\treturn nil\n\t}\n\n\tselect {\n\tcase <-time.After(5 * time.Second):\n\t\treturn errors.Errorf(\"failed to stop instance '%s'\", i.PackageID)\n\tcase <-done:\n\t\treturn nil","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/container/externalbuilder/instance.go#L142-L178","documentation":"Instance.Stop in the externalbuilder package returns this when the instance's Session field is nil, i.e. Start() was never called (or failed) before Stop() is invoked. The instance only holds a golang.org/x/sys/exec Session after a successful Start, so Stop refuses to signal a nonexistent process.","triggerScenarios":"Calling Stop() on an &externalbuilder.Instance{} that was constructed via NewInstance but never had Start() called, or calling Stop() after Start() returned an error and left Session nil.","commonSituations":"Cleanup/deferred paths that call Stop unconditionally without checking whether Start succeeded; tests that build an Instance struct manually; lifecycle code that stops instances on shutdown even for ones that never launched.","solutions":["Check i.Session != nil (or that Start returned nil error) before calling Stop.","Restructure lifecycle code so Stop is only called when the corresponding Start succeeded.","If Stop is called in a defer, guard it: if inst.Session != nil { inst.Stop() }."],"exampleFix":"// before\ninst, _ := externalbuilder.NewInstance(bldr, pkgID, releaseDir)\ndefer inst.Stop()\n// after\ninst, _ := externalbuilder.NewInstance(bldr, pkgID, releaseDir)\nif err := inst.Start(); err != nil {\n    return err\n}\ndefer inst.Stop()","handlingStrategy":"validation","validationCode":"if inst.Session == nil {\n    return errors.New(\"instance not started; skipping stop\")\n}\nif err := inst.Stop(); err != nil {\n    return err\n}","typeGuard":"func started(i *externalbuilder.Instance) bool {\n    return i != nil && i.Session != nil\n}","tryCatchPattern":null,"preventionTips":["Pair every Start with a matching Stop in the success path only.","Use defers guarded by a started flag rather than unconditional cleanup.","Check Start()'s error before any other Instance method."],"tags":["lifecycle","container","go"],"backgroundTag":"method-called-before-start","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}