Custom scalar in output is missing '@stringValue' or '@numberValue' directive, or equivalent

Issue ID: graphql-data-output-custom-scalar-directive-needed

Average severity: Critical

Description

A custom scalar is used in an output position, but it does not declare a recognized type constraint directive, such as @stringValue, @numberValue, or an equivalent directive supported by your validation framework.

For more details, see the GraphQL constraints specification.

Possible exploit scenario

Custom scalars are frequently introduced to express domain-specific types. However, without an associated constraint or validation directive, a custom scalar typically does not provide:

  • Enforceable or enforcable bounds (such as length or range)
  • Format constraints (pattern)
  • Consistent validation semantics across resolvers
  • Does not provide deterministic guarantees to API consumers

In such cases, the custom scalar effectively behaves as a renamed built-in scalar (commonly a String), providing no enforceable contract improvement and creating a false sense of security

A type constraint directive is a GraphQL directive that declares a family of constraints applicable to a scalar category, for example:

  • @stringValue:
    • Length
    • Pattern
    • Character restrictions (as supported)
  • @numberValue:
    • Minimum or maximum values (and optionally precision rules, as supported), or equivalents provided by the chosen validation framework

For output values, missing constraints can lead to:

  • Leaking unexpected or overly large values
  • Inconsistent format guarantees across services
  • Precision instability for numeric values
  • Contract drift over time
  • Increased exposure risk in federated environments
  • Inability for automated tooling to validate response guarantees

Using a recognized type constraint directive allows expressing the expected serialization shape, explicit contract-level validation expectations, and other allowed characteristics of the scalar. This makes the API contract clearer, provides cross-service consistency, strengthens data governance controls, and allows automated auditing and conformance validation.

Because unconstrained custom scalars undermine the security and reliability benefits they are intended to provide — especially for input validation — this is a critical issue.

Remediation

Include a recognized type constraint directive to all custom scalars in output positions. We recommend that you:

  • Ensure the directive family matches the scalar category (string or numeric)
  • Define at least maximum bounds (maxLength, max, or equivalent) for output values
  • Standardize constraint directives across teams and subgraphs to avoid inconsistent validation semantics
  • Avoid declaring “semantic” custom scalars without explicit validation semantics

Explicit constraint directives transform custom scalars from symbolic types into enforceable data contracts.