kopia/kopia · error
must be >= and <= or
Error message
must be >= %v and <= %v or %q
What it means
The root-cause error for all six log-detail flags: applyPolicyLogDetailPtr rejected the supplied value because strconv.Atoi failed or the integer falls outside [policy.LogDetailNone, policy.LogDetailMax]. The message itself states the accepted range and the 'inherit' alternative.
Solutions
- Read the message's range hint and retry with an integer in [LogDetailNone..LogDetailMax].
- Pass 'inherit' to reset the field to the parent policy's value.
- In automation, clamp/validate the integer against the enum bounds before calling kopia.
Example fix
// before kopia policy set /path --log-dir-snapshotted 10 // after kopia policy set /path --log-dir-snapshotted 2
Defensive patterns
Strategy: validation
Validate before calling
func clampLogDetail(v int) (policy.LogDetail, error) {
if v < int(policy.LogDetailNone) || v > int(policy.LogDetailMax) {
return 0, fmt.Errorf("log detail %d outside [%d,%d]", v, policy.LogDetailNone, policy.LogDetailMax)
}
return policy.LogDetail(v), nil
} Type guard
func isInRange(v int) bool {
return v >= int(policy.LogDetailNone) && v <= int(policy.LogDetailMax)
} Try / catch
if _, err := strconv.Atoi(s); err != nil {
return fmt.Errorf("log detail must be an integer in [%d,%d] or %q", policy.LogDetailNone, policy.LogDetailMax, "inherit")
} Prevention
- Memorize/derive the bounds from policy.LogDetailNone and policy.LogDetailMax — don't guess levels like 5 or 10.
- Offer named levels (none/1/2) in your wrapper tooling mapped to valid integers.
- Validate with the same range check the library uses before shelling out to kopia.
When it happens
Trigger: Any of --log-dir-snapshotted, --log-dir-ignored, --log-entry-snapshotted, --log-entry-ignored, --log-entry-cache-hit, --log-entry-cache-miss given a value that Atoi cannot parse (non-numeric, float, empty-with-content flags) or an integer < LogDetailNone or > LogDetailMax.
Common situations: Users guessing verbosity levels (e.g. 5, 10) beyond the small enum range; passing 'none'/'max' names instead of numbers; typos and whitespace in scripted invocations.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- directory ignored detail
- entry cache hit detail
- entry cache miss detail
- entry ignored detail
- entry snapshotted detail
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/9c3d43978e4d37fc.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command_policy_set_logging.go:77
func applyPolicyLogDetailPtr(ctx context.Context, desc string, val **policy.LogDetail, str string, changeCount *int) error {
if str == "" {
// not changed
return nil
}
if str == inheritPolicyString {
*changeCount++
log(ctx).Infof(" - resetting %q to a default value inherited from parent.", desc)
*val = nil
return nil
}
v, err := strconv.Atoi(str)
if err != nil || v < int(policy.LogDetailNone) || v > int(policy.LogDetailMax) {
return errors.Errorf("must be >= %v and <= %v or %q", policy.LogDetailNone, policy.LogDetailMax, inheritPolicyString)
}
*changeCount++
log(ctx).Infof(" - setting %q to %v.", desc, v)
ov := policy.LogDetail(v)
*val = &ov
return nil
}
View on GitHub (pinned to 82495e54b5)