AlistGo/alist · error

access_limit must be 0 or greater

Error message

access_limit must be 0 or greater

What it means

Returned by normalizeShareAccessLimit (server/handles/share.go:252) when a share create/update request carries a negative access_limit. access_limit is the number of times a share link may be accessed before it stops working; 0 means unlimited, and when burn_after_read is true a value of 0 is promoted to 1 so the link dies after the first read. Negative values have no defined meaning, so they are rejected outright.

Source

Thrown at server/handles/share.go:252

		}
		if exists {
			return "", errShareIDExists
		}
		return shareID, nil
	}
	exists, err := db.ShareIDExistsExceptID(shareID, excludeID)
	if err != nil {
		return "", fmt.Errorf("check share id availability: %w", err)
	}
	if exists {
		return "", errShareIDExists
	}
	return shareID, nil
}

func normalizeShareAccessLimit(accessLimit int64, burnAfterRead *bool) (int64, bool, error) {
	if accessLimit < 0 {
		return 0, false, fmt.Errorf("access_limit must be 0 or greater")
	}
	if accessLimit == 0 && burnAfterRead != nil && *burnAfterRead {
		accessLimit = 1
	}
	return accessLimit, accessLimit == 1, nil
}

func parseShareExpireAt(raw string) (*time.Time, error) {
	value := strings.TrimSpace(raw)
	if value == "" {
		return nil, nil
	}
	if parsed, err := time.Parse(time.RFC3339, value); err == nil {
		return &parsed, nil
	}
	layouts := []string{
		"2006-01-02T15:04:05",
		"2006-01-02T15:04",

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Send access_limit: 0 — that is the 'unlimited' value in this API
  2. Clamp any client-side computed remaining-count to 0 before submitting
  3. Add a >= 0 check in the request builder so negative values never leave the client

Example fix

// before
body := {"path": "/data/file.zip", "access_limit": -1}
// after
body := {"path": "/data/file.zip", "access_limit": 0}
Defensive patterns

Strategy: validation

Validate before calling

func validAccessLimit(v int64) bool { return v >= 0 }
// before building the request:
if !validAccessLimit(req.AccessLimit) { return fmt.Errorf("access_limit must be >= 0 (0 = unlimited)") }

Prevention

When it happens

Trigger: POST/PUT to the share create/update endpoints with a JSON body containing "access_limit": -1 or any negative number; a client computing access_limit as limit - used that underflows after concurrent downloads of the same share.

Common situations: Clients that use -1 as an 'unlimited' sentinel (this API uses 0 for unlimited); frontend forms defaulting the field to -1; decrement logic on a counter shared between requests.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/ac37981ff493464c. Report an issue: GitHub.