JanDeDobbeleer/oh-my-posh · error

unable to parse voltage_now

Error message

unable to parse voltage_now

What it means

On Linux the battery package reads sysfs files under /sys/class/power_supply/<bat>/. When energy_now is missing (or unparseable) it falls back to voltage-based charge reporting, reading voltage_now via readFloat. If that read fails (file missing, empty, or containing a non-numeric value) getByPath aborts with 'unable to parse voltage_now'.

Source

Thrown at src/runtime/battery/battery_linux.go:109

	if len(bFiles) == 0 {
		return nil, &NoBatteryError{}
	}

	return bFiles, nil
}

func getByPath(path string) (*battery, error) {
	b := &battery{}
	var err error

	if b.Current, err = readFloat(path, "energy_now"); err == nil {
		if b.Full, err = readFloat(path, "energy_full"); err != nil {
			return nil, errors.New("unable to parse energy_full")
		}
	} else {
		currentDoesNotExist := os.IsNotExist(err)
		if b.Voltage, err = readFloat(path, "voltage_now"); err != nil {
			return nil, errors.New("unable to parse voltage_now")
		}
		b.Voltage /= 1000
		if currentDoesNotExist {
			if b.Current, err = readAmp(path, "charge_now", b.Voltage); err != nil {
				return nil, errors.New("unable to parse charge_now")
			}
			if b.Full, err = readAmp(path, "charge_full", b.Voltage); err != nil {
				return nil, errors.New("unable to parse charge_full")
			}
		} else {
			if b.Full, err = readFloat(path, "energy_full"); err != nil {
				return nil, errors.New("unable to parse energy_full")
			}
		}
	}

	state, err := os.ReadFile(filepath.Join(path, "status"))
	if err != nil || len(state) == 0 {

View on GitHub (pinned to 0976794618)

Solutions

  1. Check that /sys/class/power_supply/<bat>/voltage_now exists and contains an integer (microvolts): cat /sys/class/power_supply/BAT0/voltage_now
  2. If the node is not a real battery (UPS, HID device, virtual supply), exclude it or fix the driver so type is not 'Battery' or files are complete
  3. If running in a VM/container, remove the synthetic power_supply entry or bind-mount a complete one
  4. Fall back to handling the returned error and treating the segment as no-battery

Example fix

// before (debugging shell)
cat /sys/class/power_supply/BAT0/voltage_now  # cat: ...: No such file or directory
// after (verify a complete node or pick a real battery)
ls /sys/class/power_supply/BAT0/{voltage_now,charge_now,charge_full,status}
Defensive patterns

Strategy: fallback

Validate before calling

const files = ['energy_now','voltage_now'];
for (const f of files) {
  try { const v = await Deno.readTextFile(`/sys/class/power_supply/BAT0/${f}`); if (!v.trim()) throw new Error(f); } catch { /* fall back */ }
}

Type guard

func hasVoltageNow(dir string) bool {
  b, err := os.ReadFile(filepath.Join(dir, "voltage_now"))
  return err == nil && len(strings.TrimSpace(string(b))) > 0
}

Try / catch

bat, err := battery.Get()
if err != nil {
  var noBat *battery.NoBatteryError
  if !errors.As(err, &noBat) { log.Printf("battery read failed: %v", err) }
  // render prompt without battery info
}

Prevention

When it happens

Trigger: battery.Get()/systemGetAll -> getByPath on a Linux sysfs battery whose energy_now read failed AND whose voltage_now file is absent, empty, or non-numeric.

Common situations: Virtualized/containerized environments exposing a partial power_supply node (e.g. a USB HID UPS or a virtual battery without voltage_now); exotic hardware or driver exposing only charge_* or energy_* but not voltage_now; sysfs mounted read-only or filtered.

Understand the failure class

Related errors


AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31). Data as JSON: /api/errors/f57fd0726f70d1df. Report an issue: GitHub.