JanDeDobbeleer/oh-my-posh · error

unable to parse charge_now

Error message

unable to parse charge_now

What it means

When energy_now is unavailable, the Linux battery reader derives charge as charge_now (µAh) times voltage. If charge_now cannot be read or parsed as a float, getByPath fails with 'unable to parse charge_now'.

Source

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

}

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 {
		return nil, errors.New("unable to parse or invalid status")
	}
	if b.State, err = newState(string(state[:len(state)-1])); err != nil {
		return nil, errors.New("unable to map to new state")
	}

View on GitHub (pinned to 0976794618)

Solutions

  1. Verify the file: cat /sys/class/power_supply/BAT0/charge_now; it must contain an integer in µAh
  2. If the driver exposes energy_* instead, ensure energy_now is readable so the charge path is never taken
  3. Update the kernel/driver so the battery exposes a complete charge_* or energy_* attribute set
  4. Exclude the broken power_supply node or treat the error as no-battery in the caller

Example fix

// before
$ cat /sys/class/power_supply/BAT0/charge_now
cat: /sys/class/power_supply/BAT0/charge_now: No such file or directory
// after (complete node or working energy path)
$ cat /sys/class/power_supply/BAT0/energy_now
2940000
Defensive patterns

Strategy: fallback

Validate before calling

test -s /sys/class/power_supply/BAT0/charge_now || echo "charge_now missing - battery segment will fail"

Type guard

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

Try / catch

bat, err := battery.Get()
if err != nil {
  log.Printf("skipping battery segment: %v", err)
  return nil // render without battery
}

Prevention

When it happens

Trigger: battery.Get()/systemGetAll -> getByPath on a Linux battery where energy_now is absent but charge_now is missing, empty, or non-numeric.

Common situations: Hardware/drivers exposing energy_full/voltage_now but not charge_now; sysfs node truncated by a driver bug or kernel version change; partially exposed virtual battery in a VM.

Understand the failure class

Related errors


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