1414import datadog .trace .api .featureflag .ufc .v1 .Shard ;
1515import datadog .trace .api .featureflag .ufc .v1 .ShardRange ;
1616import datadog .trace .api .featureflag .ufc .v1 .Split ;
17+ import datadog .trace .api .featureflag .ufc .v1 .ValueType ;
1718import datadog .trace .api .featureflag .ufc .v1 .Variant ;
1819import dev .openfeature .sdk .ErrorCode ;
1920import dev .openfeature .sdk .EvaluationContext ;
@@ -343,14 +344,39 @@ private static <T> ProviderEvaluation<T> resolveVariant(
343344 .build ();
344345 }
345346
347+ if (!isTypeCompatible (target , flag .variationType )) {
348+ return error (
349+ defaultValue ,
350+ ErrorCode .TYPE_MISMATCH ,
351+ "Requested type "
352+ + target .getSimpleName ()
353+ + " does not match flag variationType "
354+ + flag .variationType .name ());
355+ }
356+
357+ final T mappedValue ;
358+ try {
359+ mappedValue = mapValue (target , variant .value );
360+ } catch (final NumberFormatException e ) {
361+ return error (
362+ defaultValue ,
363+ ErrorCode .PARSE_ERROR ,
364+ "Variant '"
365+ + variant .key
366+ + "' value does not match declared type "
367+ + flag .variationType .name ()
368+ + ": "
369+ + e .getMessage ());
370+ }
371+
346372 final ImmutableMetadata .ImmutableMetadataBuilder metadataBuilder =
347373 ImmutableMetadata .builder ()
348374 .addString ("flagKey" , flag .key )
349375 .addString ("variationType" , flag .variationType .name ())
350376 .addString ("allocationKey" , allocation .key );
351377 final ProviderEvaluation <T > result =
352378 ProviderEvaluation .<T >builder ()
353- .value (mapValue ( target , variant . value ) )
379+ .value (mappedValue )
354380 .reason (Reason .TARGETING_MATCH .name ())
355381 .variant (variant .key )
356382 .flagMetadata (metadataBuilder .build ())
@@ -371,6 +397,26 @@ private static Object resolveAttribute(final String name, final EvaluationContex
371397 return context .convertValue (resolved );
372398 }
373399
400+ private static boolean isTypeCompatible (final Class <?> target , final ValueType variationType ) {
401+ if (variationType == null ) {
402+ return true ; // No type info — allow any
403+ }
404+ switch (variationType ) {
405+ case BOOLEAN :
406+ return target == Boolean .class ;
407+ case STRING :
408+ return target == String .class ;
409+ case INTEGER :
410+ return target == Integer .class ;
411+ case NUMERIC :
412+ return target == Double .class ;
413+ case JSON :
414+ return target == Value .class ;
415+ default :
416+ return true ; // Unknown types pass through — mapValue errors caught as GENERAL
417+ }
418+ }
419+
374420 @ SuppressWarnings ("unchecked" )
375421 static <T > T mapValue (final Class <T > target , final Object value ) {
376422 if (value == null ) {
0 commit comments