gohugoio/hugo · error
the seed value (%v) must be a non-negative integer
Error message
the seed value (%v) must be a non-negative integer
What it means
`collections.D` generates a deterministic sorted random sample using a PCG PRNG seeded from the first argument. The seed must cast to a non-negative int64; negative values or values that fail `cast.ToInt64E` (non-numeric strings, floats with bad format, nil) produce this error.
Source
Thrown at tpl/collections/collections.go:558
// D returns a sorted slice of unique random integers in the half-open interval
// [0, hi) using the provided seed value. The number of elements in the
// resulting slice is n or hi, whichever is less.
//
// If n <= hi, it returns a sorted random sample of size n using J. S. Vitter’s
// Method D for sequential random sampling.
//
// If n > hi, it returns the full, sorted range [0, hi) of size hi.
//
// If n == 0 or hi == 0, it returns an empty slice.
//
// Reference:
//
// J. S. Vitter, "An efficient algorithm for sequential random sampling," ACM Trans. Math. Softw., vol. 11, no. 1, pp. 37–57, 1985.
// See also: https://getkerf.wordpress.com/2016/03/30/the-best-algorithm-no-one-knows-about/
func (ns *Namespace) D(seed, n, hi any) ([]int, error) {
seedInt, err := cast.ToInt64E(seed)
if err != nil || seedInt < 0 {
return nil, fmt.Errorf("the seed value (%v) must be a non-negative integer", seed)
}
nInt, err := cast.ToIntE(n)
if err != nil || nInt < 0 || nInt > maxSeqSize {
return nil, fmt.Errorf("the number of requested values (%v) must be a non-negative integer <= %d", n, maxSeqSize)
}
hiInt, err := cast.ToIntE(hi)
if err != nil || hiInt < 0 || hiInt > maxSeqSize {
return nil, fmt.Errorf("the maximum requested value (%v) must be a non-negative integer <= %d", hi, maxSeqSize)
}
if nInt == 0 || hiInt == 0 {
return []int{}, nil
}
key := dKey{seed: uint64(seedInt), n: nInt, hi: hiInt}
View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Pass a non-negative integer seed, e.g. `{{ collections.D 42 5 100 }}`.
- To derive a seed from a string, hash it to a non-negative int first (e.g. `crypto.FNV32a`).
- Default unset params: `{{ $seed := default 0 .Params.seed }}`.
Example fix
<!-- before -->
{{ collections.D .Title 5 100 }}
<!-- after -->
{{ collections.D (crypto.FNV32a .Title) 5 100 }} Defensive patterns
Strategy: validation
Validate before calling
{{ $seed := int (default 0 .Params.seed) }}
{{ if lt $seed 0 }}{{ errorf "seed must be >= 0, got %v" $seed }}{{ end }}
{{ $sample := collections.Shuffle ... }} Type guard
{{ $validSeed := and (eq (printf "%T" $seed) "int") (ge $seed 0) }} Prevention
- Coerce seed values from front matter/params with `int` and clamp negatives (e.g. `math.Max 0 $seed`).
- Avoid deriving seeds by subtraction that can go negative.
- Use a fixed literal seed for reproducible builds instead of computed values.
When it happens
Trigger: `{{ collections.D -1 5 100 }}`, `{{ collections.D "abc" 5 100 }}`, or a nil/unset seed variable passed as the first argument.
Common situations: Deriving the seed from a hash or timestamp expression that yields a negative number; passing a page title or other string as seed expecting automatic hashing; unset param defaulting to nil.
Related errors
- the number of requested values (%v) must be a non-negative i
- errKeyIsEmptyString
- %q is not a valid duration unit
- errMustTwoNumbersError
- strings: negative Repeat count
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/da72a7c95b30cab7.json.
Report an issue: GitHub ↗.