crowdsecurity/crowdsec · error
baked-in initial_bundle.js.gz is empty (was `go generate` ru
Error message
baked-in initial_bundle.js.gz is empty (was `go generate` run?)
What it means
ChallengeRuntime.seedCacheFromInitialBundle decompresses the baked-in initial_bundle.js.gz (embedded via go:embed from `go generate`) to seed the challenge code cache. If the embedded byte slice is empty, the build artifact was never generated, so it fails with this self-diagnosing error pointing at `go generate`.
Source
Thrown at pkg/appsec/challenge/static_bundle.go:52
initialBundleOnce sync.Once
initialBundleErr error
)
// FPScannerJS is the public, unobfuscated fpscanner bundle served at
// ChallengeFPScannerPath. Re-exported so the dispatcher can serve it via the
// challenge package alongside PowWorkerJS.
var FPScannerJS = challengejs.FPScannerJS
// seedCacheFromInitialBundle decompresses the build-time obfuscated challenge
// code (initial_bundle.js.gz) and stores it as the static code served on every
// challenge page. Cheap (~ms) — eliminates the obfuscation that startup would
// otherwise pay.
func (c *ChallengeRuntime) seedCacheFromInitialBundle() error {
initialBundleOnce.Do(func() {
decompressStart := time.Now()
if len(initialBundleGz) == 0 {
initialBundleErr = errors.New("baked-in initial_bundle.js.gz is empty (was `go generate` run?)")
return
}
gz, err := gzip.NewReader(bytes.NewReader(initialBundleGz))
if err != nil {
initialBundleErr = fmt.Errorf("gzip reader for initial bundle: %w", err)
return
}
defer gz.Close()
decoded, err := io.ReadAll(gz)
if err != nil {
initialBundleErr = fmt.Errorf("decompress initial bundle: %w", err)
return
}
initialBundle = string(decoded)
c.log().WithFields(log.Fields{View on GitHub (pinned to 909b515798)
Solutions
- Run `go generate ./pkg/appsec/challenge/...` (which executes the js/cmd/bundle and initialbundle generators) and rebuild.
- Verify the generated initial_bundle.js.gz exists and is non-empty in the package directory before building.
- Check CI/build scripts include the generate step prior to `go build`.
- Ensure the file isn't excluded by .gitignore/clean rules in your checkout.
Example fix
# before: building without codegen go build ./... # after go generate ./pkg/appsec/challenge/... go build ./...
Defensive patterns
Strategy: validation
Validate before calling
// build-time check the embedded artifact is non-empty
//go:embed initial_bundle.js.gz
var initialBundleGz []byte
func init() {
if len(initialBundleGz) == 0 {
panic("initial_bundle.js.gz is empty: run `go generate` before building")
}
} Try / catch
if err := rt.seedCacheFromInitialBundle(); err != nil {
// error already names the fix; surface it at startup, not per-request
return nil, fmt.Errorf("challenge runtime init: %w", err)
} Prevention
- Run `go generate ./...` before every build from source
- Ensure CI includes the generate step prior to go build
- Don't gitignore generated artifacts needed by go:embed
- Add a build check that initial_bundle.js.gz is non-empty
When it happens
Trigger: NewChallengeRuntime calls seedCacheFromInitialBundle; on first use initialBundleOnce finds len(initialBundleGz) == 0 (static_bundle.go:52).
Common situations: Building from a source checkout without running `go generate` first; a build pipeline that skips codegen; the generated file was deleted or gitignored and never regenerated; embed directive pointing at an empty file.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- initial bundle is empty after decompression
- esbuild returned no output files
- obfuscator produced empty output
- esbuild returned no output files
- appsec datasource requires a hub. this is a bug, please repo
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/b377a5a1cacf6093.
Report an issue: GitHub.