anomalyco/sst · critical

panic(err)

Error message

panic(err)

What it means

pkg/id generates 24-character time-sortable IDs, combining the current timestamp with bytes read from crypto/rand. crypto/rand.Read fails only when the operating system's cryptographic entropy source is unavailable; the library treats this as unrecoverable (IDs must be unpredictable) and panics. Ascending() and Descending() both funnel through generateID, so any caller panics.

Solutions

  1. Restore access to the OS entropy source: allow the getrandom syscall in the container/seccomp profile or mount /dev/urandom
  2. Upgrade the container runtime/seccomp profile (e.g. docker>=20.10 default profiles allow getrandom)
  3. Rerun the process on a host with a working CSPRNG — verify with `head -c 16 /dev/urandom | xxd`
  4. If you control the code, replace panic with error propagation, though SST treats RNG failure as fatal by design

Example fix

// before (seccomp profile json)
"syscalls": [{ "names": ["getrandom"], "action": "SCMP_ACT_ERRNO" }]
// after
remove the getrandom deny rule, or run with: docker run --security-opt seccomp=default.json ...
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the CSPRNG is reachable before invoking sst code paths that generate IDs
f, err := os.Open("/dev/urandom")
if err != nil {
    return fmt.Errorf("entropy source unavailable: %w", err)
}
f.Close()

Try / catch

// cannot recover from the panic itself (library-level); guard the calling operation and surface a clear message:
func safeAscending() (id string, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("id generation failed (check CSPRNG/seccomp getrandom): %v", r)
        }
    }()
    return id.Ascending(), nil
}

Prevention

When it happens

Trigger: Any call to id.Ascending() or id.Descending() when crypto/rand.Read errors — practically only when the OS CSPRNG is unavailable: a sealed /dev/urandom-less container, getrandom(2) returning ENOSYS/EAGAIN repeatedly, or an extremely restricted seccomp/AppArmor profile blocking getrandom.

Common situations: Minimal Docker containers with restricted syscalls (seccomp profiles blocking getrandom on old Docker + new kernels); embedded/unusual Linux setups without a functional entropy pool; sandboxed CI environments.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/d4275b785da90a3f. Report an issue: GitHub.

Appendix: source

Thrown at pkg/id/id.go:33

func Descending() string {
	return generateID(true)
}

func generateID(descending bool) string {
	now := time.Now().UnixMilli()
	if descending {
		now = ^now
	}

	timeBytes := make([]byte, 6)
	for i := 0; i < 6; i++ {
		timeBytes[i] = byte(now >> (40 - 8*i))
	}

	randomBytes := make([]byte, (LENGTH-12)/2)
	_, err := rand.Read(randomBytes)
	if err != nil {
		panic(err)
	}

	result := make([]byte, LENGTH)
	hex.Encode(result[:12], timeBytes)
	hex.Encode(result[12:], randomBytes)

	return string(result)
}

View on GitHub (pinned to a0bd20f762)