Skip to content

GraphQL resolver: no int/bool/float coercion — typed fields silently null (or mismatch) for string source data #1017

Description

@bjagg

Describe the bug

LIF's data model is permissive ("no loss" — most values stored as JSON strings), but a field's MDR DataType maps it to a strict GraphQL/Python type (int/bool/float/date). When the stored value doesn't match the declared type, the GraphQL resolver mishandles it.

components/lif/openapi_to_graphql/type_factory.pydict_to_dataclass (~L560-600) coerces lists, nested objects, date, and datetime, but has no branch for int/bool/float. So a value like "Yes", "N/A", or "50" arriving for a field declared boolean/integer/number:

  • passes through uncoerced → Strawberry serialization sees a str where bool/int/float is annotated → type mismatch, and
  • the surrounding try/except sets the field to None and logs a warning (silent data loss; the code even carries a TODO: should really be more strict).

This is the value/type analogue of the name problem (#1011): permissive source data vs. a strict typed consumer.

Severity: runtime — wrong/empty values returned to the frontend, no error surfaced to the caller.

Fix direction (ties to the two entry points):

  • Data entry point: validate ingested data against its assigned schema + sanity checks (a typed field shouldn't accept a non-conforming string silently).
  • Resolver robustness: add explicit int/bool/float coercion in dict_to_dataclass (mirror the date/datetime handling), and decide a policy for non-coercible values (preserve-as-string vs. null-with-signal) rather than silent None.

Related: #1011/#1012 (name analogue), #1014 (naming/validation ADR — consider a sibling decision for type-vs-data), data-model-rules.md ("primitive JSON / strings for flexibility").

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions