seaweedfs/seaweedfs · error
dirIdleEvictSec: %s
Error message
dirIdleEvictSec: %s
What it means
runFuse in weed/command/fuse_std.go parses FUSE helper-style options (space/dash/comma separated name=value pairs, e.g. `weed fuse /mnt/sw -o filer=localhost:8888,readOnly=true`) before daemonizing into a master/child pair and calling runMount. dirIdleEvictSec (seconds an idle directory entry stays cached before eviction) is parsed with strconv.ParseInt(value, 0, 32): base 0 also accepts 0x/0o/0b prefixes; the value must be a whole number within int32 range. The panic fires on duration strings like '30m', floats, or a bare flag (a bare flag without '=' is assigned the literal value "true" by the tokenizer (fuse_std.go:46,57,102), which then fails numeric parsing).
Source
Thrown at weed/command/fuse_std.go:165
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
intValue := int(parsed)
mountOptions.chunkSizeLimitMB = &intValue
} else {
panic(fmt.Errorf("chunkSizeLimitMB: %s", err))
}
case "cacheMetaTtlSec":
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
intValue := int(parsed)
mountOptions.cacheMetaTtlSec = &intValue
} else {
panic(fmt.Errorf("cacheMetaTtlSec: %s", err))
}
case "dirIdleEvictSec":
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
intValue := int(parsed)
mountOptions.dirIdleEvictSec = &intValue
} else {
panic(fmt.Errorf("dirIdleEvictSec: %s", err))
}
case "concurrentWriters":
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
intValue := int(parsed)
mountOptions.concurrentWriters = &intValue
} else {
panic(fmt.Errorf("concurrentWriters: %s", err))
}
case "concurrentReaders":
if parsed, err := strconv.ParseInt(parameter.value, 0, 32); err == nil {
intValue := int(parsed)
mountOptions.concurrentReaders = &intValue
} else {
panic(fmt.Errorf("concurrentReaders: %s", err))
}
case "cacheDir":
mountOptions.cacheDirForRead = ¶meter.value
case "cacheCapacityMB":View on GitHub (pinned to 1c926e8fac)
Solutions
- Pass whole seconds: dirIdleEvictSec=1800 for 30 minutes
- Strip unit suffixes and decimal points
- Keep the value within int32 range
- Use name=value form, not a bare flag
Example fix
// before weed fuse /mnt/sw -o "filer=localhost:8888,dirIdleEvictSec=30m" // after weed fuse /mnt/sw -o "filer=localhost:8888,dirIdleEvictSec=1800"
Defensive patterns
Strategy: validation
Validate before calling
if v, ok := opts["dirIdleEvictSec"]; ok {
if _, err := strconv.ParseInt(v, 0, 32); err != nil {
return fmt.Errorf("dirIdleEvictSec must be int32 seconds (no units): %w", err)
}
} Type guard
func isInt32Option(v string) bool {
_, err := strconv.ParseInt(v, 0, 32)
return err == nil
} Prevention
- Treat all cache-TTL options as unitless seconds
- Keep a unit-conversion note beside tuned options in runbooks
- Validate the full option string before systemd/fstab consumes it
When it happens
Trigger: -o dirIdleEvictSec=30m; dirIdleEvictSec=1.5; bare -o dirIdleEvictSec.
Common situations: Tuning copied from blog posts that show human-readable durations; options migrated from yaml config keys that accept durations.
Related errors
AI-assisted analysis of seaweedfs/seaweedfs@1c926e8fac (2026-08-15).
Data as JSON: /api/errors/008e9867a5fdc0dc.
Report an issue: GitHub.