{"record":{"id":"aa79f673b255b55b","repo":"slimtoolkit/slim","slug":"one-or-more-monitors-failed-fanotify-error-q-pt","errorCode":null,"errorMessage":"one or more monitors failed: fanotify.error=%q, ptrace.error=%q","messagePattern":"one or more monitors failed: fanotify\\.error=%q, ptrace\\.error=%q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/app/sensor/monitor/composite.go","lineNumber":329,"sourceCode":"\n\tfor {\n\t\tselect {\n\t\tcase <-timer:\n\t\t\treturn errors\n\n\t\tcase err := <-m.errorCh:\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n}\n\nfunc (m *monitor) Status() (*CompositeReport, error) {\n\t// peReport, peErr := m.peMon.Status()\n\tfanReport, fanErr := m.fanMon.Status()\n\tptReport, ptErr := m.ptMon.Status()\n\n\tif fanErr != nil || ptErr != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"one or more monitors failed: fanotify.error=%q, ptrace.error=%q\",\n\t\t\tfanErr, ptErr,\n\t\t)\n\t}\n\n\treturn &CompositeReport{\n\t\t// PeReport: peReport,\n\t\tFanReport: fanReport,\n\t\tPtReport:  ptReport,\n\t}, nil\n}\n\nfunc NonCriticalError(err error) error {\n\treturn fmt.Errorf(\"non-critical monitor error: %w\", err)\n}\n\n// Using simple io.MultiWriter(os.Stdout, os.File) would make cmd.Wait()\n// block until either the cmd's stdout is closed or the multi-writer is closed.","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/slimtoolkit/slim/blob/81940d17fa112cc678e32209214bcb2355cb3004/pkg/app/sensor/monitor/composite.go#L311-L347","documentation":"CompositeMonitor.Status() aggregates reports from the fanotify and ptrace sub-monitors. If either sub-monitor's Status() returns an error, the composite returns a single wrapped error containing both error values. It signals that the combined monitoring status is unavailable because at least one monitor failed.","triggerScenarios":"Calling Status() on a composite monitor when m.fanMon.Status() or m.ptMon.Status() returns a non-nil error — typically because the fanotify or ptrace monitor was never started, already terminated, or its internal state collection failed.","commonSituations":"Querying status after a monitor crashed or before Start(); running on a kernel/filesystem where fanotify is unavailable; ptrace target app already exited; permission restrictions (non-root without CAP_SYS_PTRACE).","solutions":["Check the fanotify.error and ptrace.error fields in the message to see which monitor(s) failed and address the underlying cause.","Ensure both sub-monitors were started successfully (Start() returned nil) before calling Status().","Verify the process has sufficient privileges (root or CAP_SYS_PTRACE / fanotify permissions).","Handle partial failure gracefully: if one monitor's error is acceptable, call each sub-monitor's Status() individually instead of the composite."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"report, err := mon.Status()\nif err != nil {\n    var pe *fanotify.StatusError // inspect sub-errors via the message fields\n    log.Warnf(\"composite status unavailable: %v\", err)\n    // fall back to per-monitor status queries or continue with degraded monitoring\n}","preventionTips":["Only call Status() after a successful Start() on the composite monitor.","Verify kernel support and privileges (CAP_SYS_PTRACE, fanotify) before starting monitors.","Monitor sub-monitor liveness and restart failed monitors before querying status."],"tags":["monitoring","fanotify","ptrace","process"],"backgroundTag":"monitor-status-unavailable","analyzedSha":"81940d17fa112cc678e32209214bcb2355cb3004","analyzedAt":"2026-08-31T23:06:12.682Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}