hasura/graphql-engine · error · MapFieldNamesError

Value did not match object type, was expecting {expected_typ

Error message

Value did not match object type, was expecting {expected_type}

What it means

MapFieldNamesError::ExpectedAnObject is raised when the argument field-name mapper expects an object/struct-shaped value (per the schema's QualifiedTypeReference) but the actual value is a scalar, array, or otherwise non-object JSON value. The mapper needs an object so it can rename fields per the NDC field mappings, so a non-object value at that position aborts planning.

Source

Thrown at v3/crates/plan/src/query/arguments.rs:649

                }
            }
            UnresolvedArgument::Literal { value } => Argument::Literal {
                value: value.clone(),
            },
        };
        resolved_arguments.insert(argument_name, resolved_argument_value.clone());
    }

    Ok(resolved_arguments)
}

#[derive(Debug, thiserror::Error)]
pub enum MapFieldNamesError {
    #[error("Value did not match array type, was expecting {expected_type}")]
    ExpectedAnArray {
        expected_type: QualifiedTypeReference,
    },
    #[error("Value did not match object type, was expecting {expected_type}")]
    ExpectedAnObject {
        expected_type: QualifiedTypeReference,
    },
    #[error("Type mappings not found for object type {object_type_name}")]
    TypeMappingsNotFound {
        object_type_name: Qualified<CustomTypeName>,
    },
    #[error("Field mapping {field_name} not found for object type {object_type_name}")]
    FieldMappingNotFound {
        object_type_name: Qualified<CustomTypeName>,
        field_name: FieldName,
    },
    #[error("Unknown fields found in object type {object_type_name}: {fields:?}")]
    UnknownFieldsInObject {
        object_type_name: Qualified<CustomTypeName>,
        fields: Vec<String>,
    },
}

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Send a JSON object (with the correct field names) wherever the schema declares an object input type
  2. Compare the value's shape against the argument's input type in the schema/introspection
  3. Fix client variable serialization that stringifies nested objects (JSON.stringify applied at the wrong level)
  4. Update the schema type mapping if the object type is new and unmapped

Example fix

// before
variables: { "where": "{\"id\":1}" }
// after
variables: { "where": { "id": 1 } }
Defensive patterns

Strategy: validation

Validate before calling

fn assert_object_arg(name: &str, v: &serde_json::Value) -> Result<(), String> {
    v.as_object().map(|_| ()).ok_or_else(|| format!("argument '{name}' must be an object"))
}

Type guard

const isJSONObject = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);

Try / catch

Catch MapFieldNamesError::ExpectedAnObject and surface expected_type in a client-facing validation error.

Prevention

When it happens

Trigger: Passing a scalar or array where the schema declares an object input type for a command/model argument, e.g. {"where": 5} or {"filter": ["a"]} instead of {"where": {"id": {...}}}.

Common situations: Flattening or simplifying input objects on the client; sending JSON-encoded strings instead of nested objects; schema evolution turning a scalar argument into an object type; misunderstanding nested input type syntax in GraphQL variables.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/8b906ebe27a80e0f. Report an issue: GitHub.