{"record":{"id":"e77329443f920837","repo":"crowdsecurity/crowdsec","slug":"gzip-reader-for-initial-bundle-w","errorCode":null,"errorMessage":"gzip reader for initial bundle: %w","messagePattern":"gzip reader for initial bundle: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/challenge/static_bundle.go","lineNumber":58,"sourceCode":"// 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{\n\t\t\t\"compressed_bytes\":   len(initialBundleGz),\n\t\t\t\"decompressed_bytes\": len(initialBundle),\n\t\t\t\"duration_ms\":        time.Since(decompressStart).Milliseconds(),\n\t\t}).Debug(\"decompressed baked-in obfuscated challenge code\")\n\t})\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/static_bundle.go#L40-L76","documentation":"The challenge runtime decompresses the embedded initial_bundle.js.gz at startup via a sync.Once; gzip.NewReader fails when the baked-in blob is not valid gzip data. The error is cached in initialBundleErr so every subsequent request for the bundle fails the same way. This almost always means the build artifact is broken, not runtime data.","triggerScenarios":"The embedded initialBundleGz contains corrupt, empty-after-check, or non-gzip bytes — e.g. go:generate never ran, or a bad build pipeline stored a placeholder/HTML error page in the .gz file.","commonSituations":"Fresh checkout where `go generate ./pkg/appsec/challenge/...` was not run; CI builds the binary without the generate step; a partially-written or LFS-mishandled .gz asset; a stale build cache embedding an old broken blob.","solutions":["Run `go generate` (or `make build`) to (re)create initial_bundle.js.gz, then rebuild the binary","Inspect the embedded .gz file: `file initial_bundle.js.gz` and `gzip -t` to confirm it is valid gzip","Clean the build cache / rebuild from a fresh checkout so a stale blob is not embedded","Verify the build pipeline runs the generate step before `go build`"],"exampleFix":"// before: build without generated asset\ngo build ./cmd/crowdsec\n// after\ngo generate ./pkg/appsec/challenge/...\ngo build ./cmd/crowdsec","handlingStrategy":"try-catch","validationCode":"if len(initialBundleGz) == 0 || !bytes.HasPrefix(initialBundleGz, []byte{0x1f, 0x8b}) {\n    return errors.New(\"embedded initial bundle missing or not gzip\")\n}","typeGuard":null,"tryCatchPattern":"bundle, err := challenge.InitialBundle()\nif err != nil {\n    log.Error().Err(err).Msg(\"embedded bundle broken; run go generate and rebuild\")\n    http.Error(w, \"bundle unavailable\", http.StatusInternalServerError)\n    return\n}","preventionTips":["Always build via `make build`, which runs go:generate","Add `gzip -t` validation of the asset in CI before packaging","Fail the build if initial_bundle.js.gz is missing or empty","Avoid hand-editing or reformatting generated assets"],"tags":["gzip","embedded-assets","build"],"backgroundTag":"file-read-failed","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"}