AlistGo/alist · error
expire_hours must be 0 or greater
Error message
expire_hours must be 0 or greater
What it means
Returned by resolveShareExpireAt (server/handles/share.go:286) when the request supplies a negative expire_hours and no explicit expire_at string. expire_hours is a shorthand that computes the expiry timestamp as now + expire_hours; 0 disables expiry. expire_at takes priority and is parsed instead when non-empty, so this error fires only on the hours path.
Source
Thrown at server/handles/share.go:286
layouts := []string{
"2006-01-02T15:04:05",
"2006-01-02T15:04",
"2006-01-02 15:04:05",
}
for _, layout := range layouts {
if parsed, err := time.ParseInLocation(layout, value, time.Local); err == nil {
return &parsed, nil
}
}
return nil, fmt.Errorf("invalid expire_at")
}
func resolveShareExpireAt(expireAt string, expireHours int64) (*time.Time, error) {
if strings.TrimSpace(expireAt) != "" {
return parseShareExpireAt(expireAt)
}
if expireHours < 0 {
return nil, fmt.Errorf("expire_hours must be 0 or greater")
}
if expireHours == 0 {
return nil, nil
}
expires := time.Now().Add(time.Duration(expireHours) * time.Hour)
return &expires, nil
}
func sharePasswordMatched(share *model.Share, password string) bool {
if !share.HasPassword() {
return true
}
hash := sharePasswordHash(password, share.PasswordSalt)
return subtle.ConstantTimeCompare([]byte(hash), []byte(share.PasswordHash)) == 1
}
func getShareAccessToken(c *gin.Context, fallback string) string {
if fallback != "" {View on GitHub (pinned to 843d9dc814)
Solutions
- Send expire_hours: 0 to disable expiry
- If you computed the hours from a deadline, skip negative results and send 0
- Validate the field in the request builder before calling the API
Example fix
// before
{"expire_hours": -24}
// after
{"expire_hours": 0} Defensive patterns
Strategy: validation
Validate before calling
if req.ExpireHours < 0 { return fmt.Errorf("expire_hours must be >= 0 (0 = no expiry)") } Prevention
- Use 0 for 'never expires'
- Skip negative hour computations and send 0 instead
- Keep expire_at and expire_hours mutually exclusive in client forms
When it happens
Trigger: Share create/update with expire_hours: -1 in the body and an empty/absent expire_at; e.g. curl -d '{"path":"/f","expire_hours":-24}'.
Common situations: Clients using -1 to mean 'never expire' (this API uses 0); negative offsets computed from a target time already in the past.
Related errors
- access_limit must be 0 or greater
- invalid response
- share_id must be 1-32 characters of letters, numbers, unders
- illegal title, only supports 50 characters
- page can't < 1
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/b8ea8cee654303fa.
Report an issue: GitHub.