{"record":{"id":"248e62246a462b37","repo":"crowdsecurity/crowdsec","slug":"esbuild-returned-no-output-files","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/bundle/main.go","lineNumber":60,"sourceCode":"\t\tWrite:             false,\n\t\tFormat:            t.format,\n\t\tPlatform:          esbuildapi.PlatformBrowser,\n\t\tTarget:            esbuildapi.ES2022,\n\t\tMinifyWhitespace:  true,\n\t\tMinifyIdentifiers: true,\n\t\tMinifySyntax:      true,\n\t\tSourcemap:         esbuildapi.SourceMapNone,\n\t})\n\n\tif len(result.Errors) > 0 {\n\t\tfor _, msg := range result.Errors {\n\t\t\tfmt.Fprintln(os.Stderr, msg.Text)\n\t\t}\n\t\treturn fmt.Errorf(\"esbuild failed with %d error(s)\", len(result.Errors))\n\t}\n\n\tif len(result.OutputFiles) == 0 {\n\t\treturn errors.New(\"esbuild returned no output files\")\n\t}\n\n\tif err := os.WriteFile(t.outFile, result.OutputFiles[0].Contents, 0o644); err != nil {\n\t\treturn fmt.Errorf(\"write %s: %w\", t.outFile, err)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":42,"sourceCodeEnd":69,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/js/cmd/bundle/main.go#L42-L69","documentation":"In pkg/appsec/challenge/js/cmd/bundle, the build step runs esbuild API compilation; if esbuild reports success but returns zero output files, the tool has nothing to write and fails with this error. This is an invariant violation — a successful build should always produce at least one output file (the JS bundle).","triggerScenarios":"esbuild.Build (or Build with write:false) completes with no errors but result.OutputFiles is empty in build(), called from main.","commonSituations":"A misconfigured bundle entrypoint or outfile setting; an esbuild API version change changing OutputFiles semantics; plugin/loader config that silently discards output; an empty entrypoint pipeline that esbuild treats as no-op.","solutions":["Inspect the esbuild options in main.go: verify entryPoints, outfile, bundle and write:false are set so OutputFiles is populated.","Check the esbuild library version for behavioral changes in OutputFiles and pin/upgrade accordingly.","Log result.OutputFiles contents on failure to see if a plugin filtered them out.","Review custom plugins/loaders for swallowed output."],"exampleFix":"// before: no diagnostics\nif len(result.OutputFiles) == 0 {\n    return errors.New(\"esbuild returned no output files\")\n}\n// after: surface config for debugging\nif len(result.OutputFiles) == 0 {\n    return fmt.Errorf(\"esbuild returned no output files (entry=%v outfile=%s)\", opts.EntryPoints, t.outFile)\n}","handlingStrategy":"validation","validationCode":"// assert esbuild options produce output before building\nif len(opts.EntryPoints) == 0 || opts.Outfile == \"\" {\n    return errors.New(\"esbuild options missing entryPoints/outfile\")\n}\nif !opts.Write == false { /* ensure write:false for in-memory builds */ }","typeGuard":null,"tryCatchPattern":"result, err := api.Build(opts)\nif err != nil { return err }\nif len(result.Errors) > 0 { /* handle build errors */ }\nif len(result.OutputFiles) == 0 {\n    return fmt.Errorf(\"esbuild returned no output files (entry=%v outfile=%s)\", opts.EntryPoints, opts.Outfile)\n}","preventionTips":["Always set entryPoints and outfile in in-memory (write:false) builds","Pin the esbuild API version; review its changelog on upgrades","Log OutputFiles length on failure for diagnosability","Audit custom plugins for suppressed output"],"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-14T00:17:10.932Z"}