{"record":{"id":"b377a5a1cacf6093","repo":"crowdsecurity/crowdsec","slug":"baked-in-initial-bundle-js-gz-is-empty-was-go-ge","errorCode":null,"errorMessage":"baked-in initial_bundle.js.gz is empty (was `go generate` run?)","messagePattern":"baked-in initial_bundle\\.js\\.gz is empty \\(was `go generate` run\\?\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/challenge/static_bundle.go","lineNumber":52,"sourceCode":"\tinitialBundleOnce sync.Once\n\tinitialBundleErr  error\n)\n\n// FPScannerJS is the public, unobfuscated fpscanner bundle served at\n// ChallengeFPScannerPath. Re-exported so the dispatcher can serve it via the\n// challenge package alongside PowWorkerJS.\nvar FPScannerJS = challengejs.FPScannerJS\n\n// seedCacheFromInitialBundle decompresses the build-time obfuscated challenge\n// code (initial_bundle.js.gz) and stores it as the static code served on every\n// challenge page. Cheap (~ms) — eliminates the obfuscation that startup would\n// otherwise pay.\nfunc (c *ChallengeRuntime) seedCacheFromInitialBundle() error {\n\tinitialBundleOnce.Do(func() {\n\t\tdecompressStart := time.Now()\n\n\t\tif len(initialBundleGz) == 0 {\n\t\t\tinitialBundleErr = errors.New(\"baked-in initial_bundle.js.gz is empty (was `go generate` run?)\")\n\t\t\treturn\n\t\t}\n\n\t\tgz, err := gzip.NewReader(bytes.NewReader(initialBundleGz))\n\t\tif err != nil {\n\t\t\tinitialBundleErr = fmt.Errorf(\"gzip reader for initial bundle: %w\", err)\n\t\t\treturn\n\t\t}\n\t\tdefer gz.Close()\n\n\t\tdecoded, err := io.ReadAll(gz)\n\t\tif err != nil {\n\t\t\tinitialBundleErr = fmt.Errorf(\"decompress initial bundle: %w\", err)\n\t\t\treturn\n\t\t}\n\t\tinitialBundle = string(decoded)\n\n\t\tc.log().WithFields(log.Fields{","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/static_bundle.go#L34-L70","documentation":"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`.","triggerScenarios":"NewChallengeRuntime calls seedCacheFromInitialBundle; on first use initialBundleOnce finds len(initialBundleGz) == 0 (static_bundle.go:52).","commonSituations":"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.","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."],"exampleFix":"# before: building without codegen\ngo build ./...\n# after\ngo generate ./pkg/appsec/challenge/...\ngo build ./...","handlingStrategy":"validation","validationCode":"// build-time check the embedded artifact is non-empty\n//go:embed initial_bundle.js.gz\nvar initialBundleGz []byte\n\nfunc init() {\n    if len(initialBundleGz) == 0 {\n        panic(\"initial_bundle.js.gz is empty: run `go generate` before building\")\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := rt.seedCacheFromInitialBundle(); err != nil {\n    // error already names the fix; surface it at startup, not per-request\n    return nil, fmt.Errorf(\"challenge runtime init: %w\", err)\n}","preventionTips":["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"],"tags":["appsec","build","embed","javascript"],"backgroundTag":"missing-dependency","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}