{"record":{"id":"544381ef362cfb83","repo":"prometheus/node_exporter","slug":"error-obtaining-power-supply-class-info-w","errorCode":null,"errorMessage":"error obtaining power_supply class info: %w","messagePattern":"error obtaining power_supply class info: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"collector/powersupplyclass_linux.go","lineNumber":165,"sourceCode":"\tfieldDesc := prometheus.NewDesc(\n\t\tprometheus.BuildFQName(namespace, subsystem, name),\n\t\tfmt.Sprintf(\"%s value of /sys/class/power_supply/<power_supply>.\", name),\n\t\t[]string{\"power_supply\"},\n\t\tnil,\n\t)\n\n\tch <- prometheus.MustNewConstMetric(fieldDesc, valueType, value, powerSupplyName)\n}\n\nfunc getPowerSupplyClassInfo(ignore *regexp.Regexp) (sysfs.PowerSupplyClass, error) {\n\tfs, err := sysfs.NewFS(*sysPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpowerSupplyClass, err := fs.PowerSupplyClass()\n\n\tif err != nil {\n\t\treturn powerSupplyClass, fmt.Errorf(\"error obtaining power_supply class info: %w\", err)\n\t}\n\n\tfor device := range powerSupplyClass {\n\t\tif ignore.MatchString(device) {\n\t\t\tdelete(powerSupplyClass, device)\n\t\t}\n\t}\n\n\treturn powerSupplyClass, nil\n}\n","sourceCodeStart":147,"sourceCodeEnd":176,"githubUrl":"https://github.com/prometheus/node_exporter/blob/17ddd77c59ba27e1508e9f7894b1e55b44d6aed3/collector/powersupplyclass_linux.go#L147-L176","documentation":"getPowerSupplyClassInfo uses the procfs library's fs.PowerSupplyClass() to enumerate /sys/class/power_supply. When that underlying call fails, the error is wrapped as \"error obtaining power_supply class info\". This is the low-level failure point beneath the collector's Update; it indicates sysfs could not be read or parsed, not merely absence of power supplies.","triggerScenarios":"Called from Update: fs.PowerSupplyClass() returns an error — the procfs filesystem handle points at a path where /sys/class/power_supply cannot be listed or its attribute files read/parsed.","commonSituations":"--path.sysfs pointing at a wrong/unmounted directory; containers with an incomplete /sys; sysfs attribute files containing values procfs cannot parse on unusual kernels or exotic power supply devices.","solutions":["Check that the configured sysfs path (--path.sysfs) contains a readable class/power_supply directory.","Reproduce with a manual read: ls /sys/class/power_supply and cat the attribute files to find unreadable/odd entries.","If a specific device's attributes fail to parse, note the kernel version and update procfs/node_exporter, or ignore the device via the collector's ignore pattern (--collector.powersupplyclass.ignored-inodes/pattern as available)."],"exampleFix":"// before\nnode_exporter --path.sysfs=/wrong/sys\n// after\nnode_exporter --path.sysfs=/sys","handlingStrategy":"validation","validationCode":"func sysfsReady(path string) error {\n\tp := filepath.Join(path, \"class\", \"power_supply\")\n\tentries, err := os.ReadDir(p)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot list %s: %w\", p, err)\n\t}\n\tfor _, e := range entries {\n\t\tif _, err := os.ReadDir(filepath.Join(p, e.Name())); err != nil {\n\t\t\treturn fmt.Errorf(\"cannot read device %s: %w\", e.Name(), err)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if err := sysfsReady(*sysPath); err != nil {\n\tlogger.Warn(\"sysfs power_supply unreadable; skipping collector\", \"err\", err)\n} else {\n\tregistry.MustRegister(collector)\n}","preventionTips":["Confirm --path.sysfs resolves to a real sysfs mount with class/power_supply present.","Read attribute files manually on exotic hardware to catch unparseable kernel values early.","Keep node_exporter/procfs updated for new power_supply attribute parsers."],"tags":["go","linux","procfs","sysfs","powersupply"],"backgroundTag":"file-read-failed","analyzedSha":"17ddd77c59ba27e1508e9f7894b1e55b44d6aed3","analyzedAt":"2026-09-07T17:54:06.211Z","contentChangedAt":"2026-09-07T17:54:06.211Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}