JanDeDobbeleer/oh-my-posh · warning

unable to parse energy_full

Error message

unable to parse energy_full

What it means

On Linux the battery is read from sysfs files under /sys/class/power_supply/<name>/. getByPath first tries the energy_* pair: if energy_now reads OK but energy_full cannot be parsed/read, the pair is inconsistent and this error aborts that battery's info.

Source

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

		if isBattery(path) {
			bFiles = append(bFiles, path)
		}
	}

	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")
			}

View on GitHub (pinned to 0976794618)

Solutions

  1. Check the file manually: cat /sys/class/power_supply/*/energy_full - find the device with a broken value
  2. Reboot or reload the battery kernel module so the driver repopulates energy_full
  3. Update BIOS/firmware if the vendor reports a full-charge capacity of 0
  4. In the theme, conditionally render the battery segment so a single bad sysfs node doesn't break the prompt

Example fix

// before
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")
    }
// after: fall back to charge_* pair
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 if b.Charge, err2 = readFloat(path, "charge_now"); err2 == nil { ... }
Defensive patterns

Strategy: try-catch

Validate before calling

full, err := os.ReadFile("/sys/class/power_supply/BAT0/energy_full")
if err != nil || strings.TrimSpace(string(full)) == "" {
    // battery data unavailable; skip segment
}

Try / catch

info, err := battery.Get()
if err != nil {
    if strings.Contains(err.Error(), "energy_full") {
        return nil // sysfs node broken; skip segment
    }
    return err
}

Prevention

When it happens

Trigger: readFloat(path, "energy_full") fails after energy_now succeeded - i.e. energy_full is missing, unreadable (permissions), or contains a non-numeric value (e.g. empty because the driver hasn't computed full charge).

Common situations: A battery whose energy_full is empty at boot or during driver initialization; vendor firmware quirks exposing energy_now but not energy_full; reading a device directory (e.g. 'AC') that has partial files; container/VM with synthetic power_supply entries.

Understand the failure class

Related errors


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