{"record":{"id":"d9ecd91e9adcaab6","repo":"hasura/graphql-engine","slug":"expected-a-value-of-type-expected-but-got-value","errorCode":null,"errorMessage":"Expected a value of type {expected:} but got value {actual:}","messagePattern":"Expected a value of type (.+?) but got value (.+?)","errorType":"validation","errorClass":"TypecheckError","httpStatus":null,"severity":"error","filePath":"v3/crates/metadata-resolve/src/helpers/typecheck.rs","lineNumber":14,"sourceCode":"//! Functions for typechecking JSON literals against expected types\nuse std::collections::{BTreeMap, BTreeSet};\n\nuse crate::stages::object_types;\nuse crate::types::error::ShouldBeAnError;\nuse crate::{Qualified, QualifiedBaseType, QualifiedTypeName, QualifiedTypeReference};\nuse open_dds::flags::Flag;\nuse open_dds::types::{CustomTypeName, FieldName};\nuse thiserror::Error;\n\n#[derive(Error, Debug, PartialEq)]\n/// Errors that can occur when typechecking a value\npub enum TypecheckError {\n    #[error(\"Expected a value of type {expected:} but got value {actual:}\")]\n    ScalarTypeMismatch {\n        expected: open_dds::types::InbuiltType,\n        actual: serde_json::Value,\n    },\n    #[error(\"Error in array item: {inner_error:}\")]\n    ArrayItemMismatch { inner_error: Box<TypecheckError> },\n    #[error(\"Expected an array but instead got value {value:}\")]\n    NonArrayValue { value: serde_json::Value },\n    #[error(\"Expected a non-null value but received null\")]\n    NullInNonNullableColumn,\n}\n\n#[derive(Error, Debug, PartialEq)]\n/// Issues that can occur when typechecking a value against an object type\npub enum TypecheckIssue {\n    #[error(\"Expected an object value of type {expected:} but got value {actual:}\")]\n    ObjectTypeMismatch {\n        expected: Qualified<CustomTypeName>,","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/metadata-resolve/src/helpers/typecheck.rs#L1-L32","documentation":"Part of the TypecheckError enum in the metadata-resolve crate. It is raised when a literal value supplied in metadata (e.g. a default argument value or comparison operand) fails to typecheck against the declared inbuilt scalar type (Int, Float, String, Boolean, ID). The error carries both the expected inbuilt type and the actual serde_json value so the mismatch is visible in the message.","triggerScenarios":"Calling the typecheck helper for a scalar-typed argument with a JSON value of the wrong kind, e.g. passing a string \"42\" where InbuiltType::Integer is expected, or a number where a Boolean is expected.","commonSituations":"Typos in metadata YAML/JSON defaults (quoting numbers), changing a scalar type in an object type without updating literal defaults, or generating metadata programmatically with serde_json values of the wrong JSON type.","solutions":["Check the reported {expected:} inbuilt type and the {actual:} JSON value, then correct the literal in your metadata","If the value should legitimately have that shape, change the declared argument/field type to match","Quote/unquote the literal appropriately (e.g. remove quotes around a number expected to be Int)","Re-run metadata resolution to confirm the typecheck passes"],"exampleFix":"// before\narguments:\n  limit:\n    type: Int\n    default: \"10\"   # string, triggers ScalarTypeMismatch\n\n// after\narguments:\n  limit:\n    type: Int\n    default: 10","handlingStrategy":"validation","validationCode":"// Rust: validate a literal against the inbuilt type before resolving metadata\nfn matches_inbuilt(expected: &open_dds::types::InbuiltType, v: &serde_json::Value) -> bool {\n    use open_dds::types::InbuiltType::*;\n    match expected {\n        Int | Float => v.is_number(),\n        String | ID => v.is_string(),\n        Boolean => v.is_boolean(),\n    }\n}","typeGuard":null,"tryCatchPattern":"// When calling metadata-resolve stages, match on the error variant to surface field context:\nmatch result {\n    Err(resolve_error) => {\n        if let Some(TypecheckError::ScalarTypeMismatch { expected, actual }) = extract_typecheck(&resolve_error) {\n            eprintln!(\"literal {actual} does not match {expected:?}\");\n        }\n    }\n    Ok(_) => {}\n}","preventionTips":["Lint metadata defaults against declared scalar types in CI","Keep numbers unquoted and booleans unquoted in YAML defaults","Regenerate/validate defaults whenever a scalar type changes"],"tags":["metadata","typecheck","scalar","json"],"backgroundTag":"value-type-mismatch","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}