fix: fall back to call-site default for null variant properties#34
Draft
fabriziodemaria wants to merge 1 commit into
Draft
Conversation
A resolved flag property whose value is `null` was coerced to the type's zero value (`false` / `0` / `0.0` / ""`) via `unwrap_or_default()` in `into_value`, silently replacing the call-site default. A null property means the variant defines no value, so resolution must fall back to the call-site default — the same behaviour as a missing property, and what every other Confidence SDK (and all local-resolve providers) does. Skip null-valued fields during conversion so the downstream path lookup misses and the default is served. Adds regression tests for a null top-level property and a null nested-struct property. Fixes spotify#33 Co-authored-by: Cursor <cursoragent@cursor.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.
Summary
Closes #33.
When a resolved flag property has the value
null, the SDK currently serves the type's zero value (false/0/0.0/"") instead of the call-site default. Anullproperty means the variant defines no concrete value, so resolution should fall back to the call-site default — the same behaviour as a missing property, and what every other Confidence SDK (and all local-resolve providers inconfidence-resolver) does.Root cause
In
confidence/src/models.rs,into_valuecoerces each field by schema type:For a JSON
null,serde_json'sas_bool()/as_i64()/as_f64()/as_str()returnNone, sounwrap_or_default()produces the zero value. That concrete zero is stored as e.g.ConfidenceValue::Bool(false), thenprocess_flagreturns it withTargetingMatchand the call-site default is never consulted. (ConfidenceValuehas noNullvariant, sonullcan't be represented as a value.)Fix
Skip null-valued fields during conversion. The downstream path lookup in
process_flagthen misses, which surfaces the call-site default — exactly how a missing property already behaves. This is the minimal change; it deliberately treatsnullas "absent" rather than introducing a newConfidenceValue::Nullvariant (which would touch every exhaustivematch).Tests
Adds two regression tests in
models.rs:null_valued_property_is_omitted_so_resolution_falls_back_to_default— a top-levelnullproperty is omitted (would beBool(false)before the fix), non-null siblings untouched.null_valued_nested_property_is_omitted— same for a property inside a nested struct.cargo testinconfidence/: 12 passed (10 prior + 2 new).Why draft
Opening as draft for maintainer review of the approach. Two open questions:
nullinstead be a first-classConfidenceValue::Nullso the nativeget_flagreturnsOk(default)rather than routing through the not-found/Errpath? The OpenFeature provider returns the default either way, but the native API semantics differ.cargo fmt-clean onmain(e.g.confidence_value.rsuses 2-space indent), so I matchedmodels.rs's existing 4-space style rather than runningcargo fmt. Happy to align to whatever you prefer.Context
Found while auditing null-property resolution semantics across all Confidence SDKs + the local-resolve providers. 12 of 13 implementations return the call-site default for a null property; this standalone Rust SDK was the lone exception.
Made with Cursor