fix(openfeature-provider/go): prevent silent SIGSEGV when recovery closes an instance mid-resolve - #512
Merged
fabriziodemaria merged 5 commits intoAug 12, 2026
Conversation
…oses an instance mid-resolve
fabriziodemaria
approved these changes
Aug 11, 2026
Member
There was a problem hiding this comment.
Reviewed — this looks like the right fix for the cored crashes in #511.
Minor follow-up (non-blocking): consider also skipping cached nil entries on load, not just guarding the fresh lookup path:
if fn, ok := r.fnCache.Load(name); ok && fn != nil {
return fn.(api.Function)
}Prevents a stale cached nil from ever reaching fn.Call if one was stored before this fix.
…ecret is unset Fork PRs do not receive repository secrets, so CONFIDENCE_CLIENT_SECRET is empty. Skip e2e and flag-logs tests gracefully instead of failing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…signature NewWasmResolverFactory now takes a second bool argument (useInterpreter) after the UseWasmInterpreter feature merged to main. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #511.
Problem
RecoveringResolver.startRecreatecloses the old wazero instance in a background goroutine. A concurrent resolve can still be mid-call on that instance, because pool slots only take a sharedRLockper resolve.WasmResolver.callholdsr.mufor the duration of a call, butClosedoes not take it. The close therefore lands mid-call. A resolve that races with the close can get a nilapi.FunctionfromExportedFunction, andexportedFunctioncaches the nil. The nextfn.Calldereferences the nil interface. The Go runtime cannot attribute that fault, so it kills the process silently (sigfwdgo → dieFromSignal(SIGSEGV), exit 139, no traceback). See #511 for the core dump analysis.Changes
WasmResolver.Closenow takesr.muaroundinstance.Close. This serializes close with in-flight calls and removes the race window. Primary fix.exportedFunctionpanics with a clear message instead of returning nil, and never caches a nil handle. This is hardening.withRecoveralready catches panics on this path, so a residual nil becomes a recovered evaluation error instead of silent process death.Testing
TestResolveOnClosedInstancePanicspins the closed-instance contract. A resolve on a closed instance must end in a recoverable panic. It must never reachfn.Callthrough a nil handle. The test closes the raw instance directly, becauseWasmResolver.Closeflushes logs first and that would warmfnCache. The direct close exercises the post-closeExportedFunctionpath.go test ./confidence/internal/local_resolver/passes.Callfails with a recoverable error. The test therefore pins the contract, not the exact race. The two production cores in Silent process crash (SIGSEGV, no traceback): recovery closes the wasm instance while concurrent resolves still use it #511 are the evidence for the race itself.TestFlagResolve_*e2e tests fail with "ClientSecret is required" both with and without this change. They need credentials this environment does not have.