From cdb6882002c36d835928fb78dcdcaf6d757ec5e1 Mon Sep 17 00:00:00 2001 From: Scott Walkinshaw Date: Wed, 7 Jan 2026 15:05:55 -0500 Subject: [PATCH] Reject enum literals for custom scalar values Enum literal values were being allowed and then coerced to Ruby strings in bluejay-rb. They should be rejected during validation up front. --- bluejay-validator/src/value/input_coercion.rs | 8 ++++++++ ...ation_test__error@value_is_valid.graphql.snap | 16 ++++++++++++++++ .../executable/error/value_is_valid.graphql | 10 ++++++++++ .../tests/test_data/executable/schema.graphql | 3 +++ 4 files changed, 37 insertions(+) diff --git a/bluejay-validator/src/value/input_coercion.rs b/bluejay-validator/src/value/input_coercion.rs index ae657b98..00b0c647 100644 --- a/bluejay-validator/src/value/input_coercion.rs +++ b/bluejay-validator/src/value/input_coercion.rs @@ -193,6 +193,14 @@ fn coerce_custom_scalar_value<'a, const CONST: bool, V: Value>( value: &'a V, path: Path<'a>, ) -> Result<(), Vec>> { + if matches!(value.as_ref(), ValueReference::Enum(_)) { + return Err(vec![Error::NoImplicitConversion { + value, + input_type_name: cstd.name().to_string(), + path, + }]); + } + cstd.coerce_input(value).map_err(|message| { vec![Error::CustomScalarInvalidValue { value, diff --git a/bluejay-validator/tests/snapshots/executable_integration_test__error@value_is_valid.graphql.snap b/bluejay-validator/tests/snapshots/executable_integration_test__error@value_is_valid.graphql.snap index 9fbd55ed..3348228a 100644 --- a/bluejay-validator/tests/snapshots/executable_integration_test__error@value_is_valid.graphql.snap +++ b/bluejay-validator/tests/snapshots/executable_integration_test__error@value_is_valid.graphql.snap @@ -29,6 +29,22 @@ Error: Object with multiple entries for field name │ ╰─── Entry for field ────╯ +Error: No implicit conversion of enum to Int + ╭─[ value_is_valid.graphql:22:25 ] + │ + 22 │ intArgField(intArg: SomeEnumValue) + │ ──────┬────── + │ ╰──────── No implicit conversion to Int +────╯ + +Error: No implicit conversion of enum to CustomScalar + ╭─[ value_is_valid.graphql:27:38 ] + │ + 27 │ customScalarField(customScalarArg: SomeEnumValue) + │ ──────┬────── + │ ╰──────── No implicit conversion to CustomScalar +────╯ + Error: No implicit conversion of string to Int ╭─[ value_is_valid.graphql:2:23 ] │ diff --git a/bluejay-validator/tests/test_data/executable/error/value_is_valid.graphql b/bluejay-validator/tests/test_data/executable/error/value_is_valid.graphql index c409619b..54cb87af 100644 --- a/bluejay-validator/tests/test_data/executable/error/value_is_valid.graphql +++ b/bluejay-validator/tests/test_data/executable/error/value_is_valid.graphql @@ -16,3 +16,13 @@ query inputFieldDoesNotExist { query duplicateInputField { findDog(complex: { name: "Fido", name: "Fido" }) { name } } + +query enumLiteralForBuiltinScalar { + arguments { + intArgField(intArg: SomeEnumValue) + } +} + +query enumLiteralForCustomScalar { + customScalarField(customScalarArg: SomeEnumValue) +} diff --git a/bluejay-validator/tests/test_data/executable/schema.graphql b/bluejay-validator/tests/test_data/executable/schema.graphql index 9ac06cbb..9b7b0704 100644 --- a/bluejay-validator/tests/test_data/executable/schema.graphql +++ b/bluejay-validator/tests/test_data/executable/schema.graphql @@ -9,8 +9,11 @@ type Query { oneOf(oneOfArg: OneOfInput!): String oneOfList(oneOfListArg: [OneOfInput]!): String nestedOneOf(nestedOneOfArg: NestedOneOfInput!): String + customScalarField(customScalarArg: CustomScalar!): String } +scalar CustomScalar + input OneOfInput @oneOf { oneOfField: String anotherField: String