{"record":{"id":"7b66277e74348800","repo":"crowdsecurity/crowdsec","slug":"failed-to-instantiate-wasi-w","errorCode":null,"errorMessage":"failed to instantiate WASI: %w","messagePattern":"failed to instantiate WASI: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/challenge/challenge.go","lineNumber":451,"sourceCode":"\n\tcryptoPoolSize := resolvedOpts.cryptoObfuscationPoolSize\n\tif cryptoPoolSize <= 0 {\n\t\tcryptoPoolSize = cryptoObfuscationPoolDefaultSize\n\t}\n\n\tspentSetMaxEntries := resolvedOpts.spentSetMaxEntries\n\tif spentSetMaxEntries <= 0 {\n\t\tspentSetMaxEntries = spentSetDefaultMaxEntries\n\t}\n\n\tr, err := newWazeroRuntime(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// No need to keep the closer around, we can just close the runtime itself when stopping\n\tif _, err := wasi_snapshot_preview1.Instantiate(ctx, r); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to instantiate WASI: %w\", err)\n\t}\n\n\tcompiledMod, err := compileObfuscatorModule(ctx, r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// We use text/template instead of html/template because the data we send\n\t// is pretty much hardcoded and trusted; html/template would escape the JS\n\t// we inject. Parsed once here so GetChallengePage doesn't re-parse on\n\t// every request.\n\thtmlTpl, err := template.New(\"challenge\").Parse(htmlTemplate)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse challenge html template: %w\", err)\n\t}\n\n\tchallengeRuntime := &ChallengeRuntime{\n\t\tr:                  r,","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/challenge.go#L433-L469","documentation":"NewChallengeRuntime wraps wasi_snapshot_preview1.Instantiate failure with 'failed to instantiate WASI'. WASI must be available in the wazero runtime before instantiating the obfuscator module; failure indicates a wazero runtime/context problem rather than bad config.","triggerScenarios":"NewChallengeRuntime -> wasi_snapshot_preview1.Instantiate(ctx, r) errors — already-instantiated WASI in the runtime, cancelled context, or wazero internal failure.","commonSituations":"Reusing a runtime where WASI was already instantiated; a context cancelled during startup shutdown; wazero version bugs.","solutions":["Ensure WASI is instantiated exactly once per runtime (NewChallengeRuntime creates its own runtime, so avoid double instantiation in modified code).","Check the wrapped error for 'context canceled' and fix premature shutdown of the runtime during startup.","Rebuild against the pinned wazero version; try a clean rebuild.","Report upstream with the wrapped error if it reproduces on an unmodified build."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Ensure single WASI instantiation per runtime in tests\nwasTestingInOnce sync.Once // guard wasi_snapshot_preview1.Instantiate in test helpers","typeGuard":null,"tryCatchPattern":"if _, err := wasi_snapshot_preview1.Instantiate(ctx, r); err != nil {\n    if errors.Is(err, context.Canceled) { /* shutdown raced startup; retry or ignore */ }\n    return nil, fmt.Errorf(\"failed to instantiate WASI: %w\", err)\n}","preventionTips":["Never reuse a runtime across NewChallengeRuntime calls in tests","Keep startup contexts alive until initialization completes","Pin the wazero version; test runtime construction in CI"],"tags":["go","wasm","wazero","wasi"],"backgroundTag":"module-init-failed","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"}