hasura/graphql-engine · error · TypecheckIssue

Expected an object value of type {expected:} but got value {

Error message

Expected an object value of type {expected:} but got value {actual:}

What it means

A TypecheckIssue (not TypecheckError) raised when typechecking a value against an object type (Qualified<CustomTypeName>) and the JSON value is not a JSON object. It names the expected custom object type and shows the actual value received.

Source

Thrown at v3/crates/metadata-resolve/src/helpers/typecheck.rs:30

/// Errors that can occur when typechecking a value
pub enum TypecheckError {
    #[error("Expected a value of type {expected:} but got value {actual:}")]
    ScalarTypeMismatch {
        expected: open_dds::types::InbuiltType,
        actual: serde_json::Value,
    },
    #[error("Error in array item: {inner_error:}")]
    ArrayItemMismatch { inner_error: Box<TypecheckError> },
    #[error("Expected an array but instead got value {value:}")]
    NonArrayValue { value: serde_json::Value },
    #[error("Expected a non-null value but received null")]
    NullInNonNullableColumn,
}

#[derive(Error, Debug, PartialEq)]
/// Issues that can occur when typechecking a value against an object type
pub enum TypecheckIssue {
    #[error("Expected an object value of type {expected:} but got value {actual:}")]
    ObjectTypeMismatch {
        expected: Qualified<CustomTypeName>,
        actual: serde_json::Value,
    },

    #[error("Typecheck failed for field {field_name:} in object type {object_type:}: {error:}")]
    ObjectTypeField {
        field_name: FieldName,
        object_type: Qualified<CustomTypeName>,
        error: TypecheckError,
    },

    #[error(
        "Found a literal value but the argument is a boolean expression type '{boolean_expression_type_name}'"
    )]
    LiteralValueUsedForBooleanExpression {
        boolean_expression_type_name: Qualified<CustomTypeName>,
    },

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Replace the literal with a mapping of field names to values
  2. Verify the value's keys match the fields of the named object type
  3. Check YAML indentation so the default is parsed as a map

Example fix

// before
# Where type is object type User
default: "User"

// after
default:
  id: 1
  name: alice
Defensive patterns

Strategy: type-guard

Type guard

fn is_json_object(v: &serde_json::Value) -> bool {
    v.is_object()
}

Try / catch

if let TypecheckIssue::ObjectTypeMismatch { expected, actual } = issue {
    eprintln!("value for {expected:?} must be a mapping, got {actual}");
}

Prevention

When it happens

Trigger: Passing a scalar, array, or string literal where an object type is expected, e.g. an argument typed as a custom object type given default: "something".

Common situations: Misconfigured defaults for object-typed arguments, confusing an object type with its name (passing the type name string instead of a mapping), malformed YAML that parses as a scalar instead of a map.

Related errors


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