matryer/xbar · warning
bad interval value: %s
Error message
bad interval value: %s
What it means
parseInterval splits the interval token into a numeric part and unit suffix, then uses strconv.ParseInt on the numeric part. If the number does not parse, it returns defaultRefreshInterval and errors.Errorf("bad interval value: %s", valStr). ParseFilenameInterval then re-wraps this with the filename. The value part must be a plain base-10 integer.
Source
Thrown at pkg/plugins/refresh_interval.go:162
return interval
}
func parseInterval(interval string) (RefreshInterval, error) {
var (
unit string
valStr string
)
switch {
case strings.HasSuffix(interval, "ms"):
unit = "ms"
valStr = interval[:len(interval)-2]
default:
unit = string(interval[len(interval)-1])
valStr = interval[:len(interval)-1]
}
val, err := strconv.ParseInt(valStr, 10, 64)
if err != nil {
return defaultRefreshInterval, errors.Errorf("bad interval value: %s", valStr)
}
switch unit {
case "d": // turn days into hours
return RefreshInterval{N: val, Unit: "days"}, nil
case "h":
return RefreshInterval{N: val, Unit: "hours"}, nil
case "m":
return RefreshInterval{N: val, Unit: "minutes"}, nil
case "s":
return RefreshInterval{N: val, Unit: "seconds"}, nil
case "ms":
return RefreshInterval{N: val, Unit: "milliseconds"}, nil
default:
return defaultRefreshInterval, errors.Errorf("bad interval unit: %s", string(unit))
}
}
View on GitHub (pinned to d624239058)
Solutions
- Edit the plugin filename so the value is a bare integer: 1.5h -> 90m, 0.5d -> 12h
- If you control the input, strip whitespace and validate with a regexp like ^\d+(ms|d|h|m|s)$ before parsing/renaming
- Rely on the returned default interval (1 minute) if the file cannot be renamed and the error is non-fatal
Example fix
// before
// file: weather.1.5h.py -> bad interval value: 5.5h
iv, err := plugins.ParseFilenameInterval("weather.1.5h.py")
// after
// rename to weather.90m.py
iv, err := plugins.ParseFilenameInterval("weather.90m.py") // -> {90, minutes} Defensive patterns
Strategy: type-guard
Validate before calling
var tokenRe = regexp.MustCompile(`^(\d+)(ms|[dhms])$`)
func intervalTokenValid(name string) bool {
tok := lastDottedSegment(strings.TrimSuffix(name, ".stp"))
return tok == "" || tokenRe.MatchString(tok)
} Try / catch
iv, err := plugins.ParseFilenameInterval(filename)
if err != nil && strings.Contains(err.Error(), "bad interval value") {
// value part was not an integer; fall back to default already returned
iv = plugins.RefreshInterval{N: 1, Unit: "minutes"}
} Prevention
- Keep the numeric part of interval tokens a bare base-10 integer (no fractions, no spaces)
- Convert fractional intervals (1.5h) to whole smaller units (90m) when renaming files
- Validate plugin filenames with a regexp before installing
When it happens
Trigger: ParseFilenameInterval on a filename whose interval token has a non-integer value: "weather.5m.py" mis-typed as "weather..m.py" (valStr "" fails), "weather.5.5m.py" (valStr "5.5"), or "weather.fivem.py" (valStr "five").
Common situations: Fractional intervals like 1.5h written into filenames; typos after manual renames; interval token accidentally including extra characters from the name; plugin authors writing 0-prefix or signed values like +5m (actually +5 parses fine, but spaces do not).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- %s (from %s)
- not an xbar:// url
- unsupported action %q
- malformed xbar.var format
- malformed xbar.var format (missing select options)
AI-assisted analysis of matryer/xbar@d624239058 (2026-09-02).
Data as JSON: /api/errors/a48a2e0fde4acc13.
Report an issue: GitHub.