{"record":{"id":"099bb5153e44acd0","repo":"crowdsecurity/crowdsec","slug":"esbuild-returned-no-output-files-099bb5","errorCode":null,"errorMessage":"esbuild returned no output files","messagePattern":"esbuild returned no output files","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/challenge/js/cmd/obfuscate/main.go","lineNumber":79,"sourceCode":"\nfunc buildObfuscatorBundle() ([]byte, error) {\n\tresult := esbuildapi.Build(esbuildapi.BuildOptions{\n\t\tEntryPoints: []string{entryPoint},\n\t\tBundle:      true,\n\t\tWrite:       false,\n\t\tFormat:      esbuildapi.FormatIIFE,\n\t\tPlatform:    esbuildapi.PlatformBrowser,\n\t\tTarget:      esbuildapi.ES2022,\n\t\tSourcemap:   esbuildapi.SourceMapNone,\n\t\t// JS obfuscator expects window/global to be available, but in WASM we don't have them, so we alias them to globalThis\n\t\tBanner: map[string]string{\"js\": \"var self=globalThis; var window=globalThis; var global=globalThis;\"},\n\t})\n\n\tif len(result.Errors) > 0 {\n\t\treturn nil, fmt.Errorf(\"esbuild failed with %d error(s): %s\", len(result.Errors), result.Errors[0].Text)\n\t}\n\tif len(result.OutputFiles) == 0 {\n\t\treturn nil, errors.New(\"esbuild returned no output files\")\n\t}\n\n\treturn result.OutputFiles[0].Contents, nil\n}\n\nfunc computeBuildKey(bundleData []byte) (string, error) {\n\tout, err := exec.CommandContext(context.Background(), \"javy\", \"--version\").Output()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to run 'javy --version' (is javy in PATH?): %w\", err)\n\t}\n\n\treturn fmt.Sprintf(\"bundle-sha256=%x %s\", sha256.Sum256(bundleData), strings.TrimSpace(string(out))), nil\n}\n\n// currentBuildKey returns the build key recorded in the existing wasm.gz\n// header, or \"\" if the file is missing or unreadable.\nfunc currentBuildKey() string {\n\tf, err := os.Open(wasmGzFile)","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/js/cmd/obfuscate/main.go#L61-L97","documentation":"In the obfuscate command, buildObfuscatorBundle runs esbuild with write:false to produce the obfuscator bundle in memory; if esbuild succeeds with no errors but returns zero output files, there is nothing to return and the function fails with this error. Like error 224 it is an internal invariant: a successful in-memory build should always yield OutputFiles.","triggerScenarios":"esbuild build with write:false completes cleanly but result.OutputFiles is empty in buildObfuscatorBundle, called from main.","commonSituations":"Missing or misconfigured outfile/entryPoints options; esbuild version differences in OutputFiles behavior; a custom plugin suppressing output; wrong bundle options that make the build a no-op.","solutions":["Verify esbuild build options include correct entryPoints, bundle:true and write:false so OutputFiles is populated.","Check for plugins/loaders that intercept and drop output files.","Compare the esbuild library version against the one used when the tool last worked; adjust the API usage.","Add debug logging of build options and result metadata when this fires."],"exampleFix":"// before\nif len(result.OutputFiles) == 0 {\n    return nil, errors.New(\"esbuild returned no output files\")\n}\n// after: include build context in the failure\nif len(result.OutputFiles) == 0 {\n    return nil, fmt.Errorf(\"esbuild returned no output files (entry=%v)\", opts.EntryPoints)\n}","handlingStrategy":"validation","validationCode":"if len(opts.EntryPoints) == 0 {\n    return nil, errors.New(\"buildObfuscatorBundle: no entryPoints configured\")\n}","typeGuard":null,"tryCatchPattern":"result, err := api.Build(opts)\nif err != nil { return nil, err }\nif len(result.OutputFiles) == 0 {\n    return nil, fmt.Errorf(\"esbuild returned no output files (entry=%v)\", opts.EntryPoints)\n}\nreturn result.OutputFiles[0].Contents, nil","preventionTips":["Verify entryPoints/bundle/write options on every esbuild API call","Pin esbuild version and re-test bundle generation on upgrades","Log build options when the output is empty","Cover bundle generation with a smoke test in CI"],"tags":["build","esbuild","javascript","tooling"],"backgroundTag":"empty-result-set","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}