{"record":{"id":"8b95807d95007307","repo":"kataras/iris","slug":"err-8b9580","errorCode":null,"errorMessage":"err","messagePattern":"err","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"middleware/monitor/monitor.go","lineNumber":76,"sourceCode":"\t}\n\n\tif opts.RefreshInterval <= 0 {\n\t\topts.RefreshInterval = 2 * opts.RefreshInterval\n\t}\n\n\tif opts.ViewRefreshInterval <= 0 {\n\t\topts.ViewRefreshInterval = opts.RefreshInterval\n\t}\n\n\tviewRefreshIntervalBytes := []byte(fmt.Sprintf(\"%d\", opts.ViewRefreshInterval.Milliseconds()))\n\tviewBody := bytes.Replace(defaultViewBody, viewRefreshIntervalTmplVar, viewRefreshIntervalBytes, 1)\n\tviewAnimationIntervalBytes := []byte(fmt.Sprintf(\"%d\", opts.ViewAnimationInterval.Milliseconds()))\n\tviewBody = bytes.Replace(viewBody, viewAnimationIntervalTmplVar, viewAnimationIntervalBytes, 2)\n\tviewTitleBytes := []byte(opts.ViewTitle)\n\tviewBody = bytes.Replace(viewBody, viewTitleTmplVar, viewTitleBytes, 2)\n\tproc, err := process.NewProcess(opts.PID)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tsh := startNewStatsHolder(proc, opts.RefreshInterval)\n\tm := &Monitor{\n\t\topts:     opts,\n\t\tHolder:   sh,\n\t\tviewBody: viewBody,\n\t}\n\n\treturn m\n}\n\n// Stop terminates the retrieve stats loop for\n// the process and the operating system statistics.\n// No other monitor instance should be initialized after the first Stop call.\nfunc (m *Monitor) Stop() {\n\tm.Holder.Stop()\n}","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/middleware/monitor/monitor.go#L58-L94","documentation":"monitor.New builds the monitoring middleware and attaches to the process identified by opts.PID using gopsutil's process.NewProcess. If no such process exists (or it cannot be inspected), New panics. The Monitor middleware must observe a real, live process at construction time.","triggerScenarios":"Calling monitor.New(monitor.DefaultConfiguration) inside a container or restricted environment where /proc access to the given PID fails, or configuring a PID that is not the current process and does not exist. The default PID is the current process (os.Getpid()), so the panic usually means /proc is unavailable or the process exited.","commonSituations":"Running inside minimal Docker/alpine images or Kubernetes sidecars without /proc mounted readably; hardened containers (hidepid); passing a parent PID from an env var that is empty; using a PID from another PID namespace.","solutions":["Keep the default PID (zero/current process) or set Configuration.PID to os.Getpid().","Ensure /proc is accessible: run the container with sufficient privileges or mount /proc properly.","Verify the target process exists before constructing: check process.PidExists from gopsutil or guard with a recover."],"exampleFix":"// before\ncfg := monitor.DefaultConfiguration\ncfg.PID = pidFromEnv // empty -> invalid\nm := monitor.New(cfg)\n// after\ncfg := monitor.DefaultConfiguration\ncfg.PID = os.Getpid()\nm := monitor.New(cfg)","handlingStrategy":"fallback","validationCode":"if cfg.PID != 0 {\n    exists, err := process.PidExists(int32(cfg.PID))\n    if err != nil || !exists {\n        return fmt.Errorf(\"monitor pid %d unavailable: %w\", cfg.PID, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        log.Printf(\"monitor disabled: %v\", r)\n    }\n}()\nm := monitor.New(cfg)","preventionTips":["Leave PID at its default (current process) unless you specifically monitor another process.","Ensure /proc is readable when running in containers (mount procfs, avoid hidepid).","Construct the monitor lazily with recover so a hostile environment degrades instead of crashing."],"tags":["go","panic","monitoring","process","gopsutil","container"],"backgroundTag":"process-not-found","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}