Skip to content

Fix/forced variations double format exception#152

Open
vazarkevych wants to merge 4 commits into
growthbook:mainfrom
vazarkevych:fix/forced-variations-double-format-exception
Open

Fix/forced variations double format exception#152
vazarkevych wants to merge 4 commits into
growthbook:mainfrom
vazarkevych:fix/forced-variations-double-format-exception

Conversation

@vazarkevych

Copy link
Copy Markdown
Collaborator

fix: handle int, double, and string values in forcedVariationsMap to prevent FormatException

Problem

forcedVariationsMap is typed as Map<String, dynamic>, so when variation values are deserialized from JSON, numeric values can arrive as double (e.g. 1.0) instead of int. The previous implementation converted any value to a string and called int.parse(), which throws a FormatException on inputs like "1.0":

int.parse(1.0.toString()); // FormatException: Invalid radix-10 number

This was a runtime crash for any integration passing numeric variation indices through JSON.


Solution

Replace the int.parse(.toString()) call in experiment_evaluator.dart with explicit type-aware parsing:

  • int → used directly
  • double → converted via .toInt()
  • String → tried with int.tryParse, then double.tryParse(...).toInt() as fallback
  • Unsupported types (e.g. bool, objects) → log a warning and skip the forced variation gracefully instead of crashing

Test Cases Added

Input Result
1 (int) variationID = 1
1.0 (double) variationID = 1
"1" (string) variationID = 1
"1.0" (string) variationID = 1
"abc" no crash, forced variation skipped
true no crash, forced variation skipped

Backward Compatibility

Existing integrations passing integer values are unaffected — the int branch is the first check and returns immediately.

@madhuchavva madhuchavva left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline review comment on forced variation parsing semantics.

int? forcedVariationIndex;
if (rawValue is int) {
forcedVariationIndex = rawValue;
} else if (rawValue is double) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch on int.parse(value.toString()); that crash is worth fixing. I think this parsing should be stricter before merge: double.toInt() silently turns values like 1.9 into variation 1, and string parsing via double.tryParse(rawValue)?.toInt() has the same issue. Forced variation IDs should be exact finite integer indexes, so we should only accept integer-valued numbers/strings (1, 1.0, "1", "1.0") and skip/log fractional or non-finite values. It would also be useful to validate the parsed index against experiment.variations before returning the forced result.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — updated the parsing to only accept integer-valued numbers for doubles, same for string-parsed doubles and added bounds validation against experiment.variations.length before applying the forced result. Fractional or out-of-bounds values are now logged and skipped. Tests added for all new cases.

@madhuchavva madhuchavva left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes based on the inline review comments. The notes call out functional gaps or compatibility/documentation risks that should be addressed before merge.

@vazarkevych vazarkevych requested a review from madhuchavva June 11, 2026 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants