dbt-labs/dbt-core · error
remote_state must be Object
Error message
remote_state must be Object
What it means
After the None check, the BigQuery branch calls `as_object()` on remote_state_value and errors if it is not a minijinja object. The state must be an object that can be downcast to a RelationConfig; anything else (string, number, array, plain dict of the wrong shape) produces this InvalidArgument error.
Source
Thrown at crates/dbt-adapter/src/relation/relation_impl.rs:1284
RedshiftMaterializedViewConfigChangeset::new(remote_state, local_config);
if changeset.has_changes() {
Ok(Value::from_object(changeset))
} else {
Ok(Value::from(None::<()>))
}
}
Bigquery => {
if remote_state_value.is_none() {
return Err(minijinja::Error::new(
minijinja::ErrorKind::InvalidArgument,
"remote_state cannot be None",
));
}
let current_state = remote_state_value
.as_object()
.ok_or_else(|| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidArgument,
"remote_state must be Object",
)
})?
.downcast_ref::<RelationConfig>()
.ok_or_else(|| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidArgument,
"remote_state must be RelationConfig",
)
})?;
// TODO(serramatutu): minijinja_value_to_typed_struct does not work with
// references, so we have to clone the value here...
let local_config = minijinja_value_to_typed_struct::<InternalDbtNodeWrapper>(
local_config_value.clone(),
)
.map_err(|e| {View on GitHub (pinned to 0267ce9170)
Solutions
- Pass the RelationConfig object returned by the adapter's remote-state/describe API rather than a raw dict.
- If constructing state manually, build a RelationConfig via the adapter's relation helpers so downcast succeeds.
- Ensure you are not crossing adapter boundaries (BigQuery state must come from BigQuery describe results).
Example fix
// before
relation.changeset(remote_state={'columns': cols})
// after
relation.changeset(remote_state=remote_state) # RelationConfig object from adapter Defensive patterns
Strategy: type-guard
Validate before calling
{% if remote_state is not mapping %}
{{ exceptions.raise_compiler_error('remote_state must be a RelationConfig object') }}
{% endif %} Type guard
fn is_relation_config(v: &Value) -> bool {
v.as_object()
.and_then(|o| o.downcast_ref::<RelationConfig>())
.is_some()
} Try / catch
let cfg = remote_state_value.as_object()
.and_then(|o| o.downcast_ref::<RelationConfig>())
.ok_or_else(|| warn_and_refetch(relation))?; Prevention
- Pass RelationConfig objects, never plain dicts or primitives
- Do not mix remote state across adapters
- Avoid serializing/deserializing state in ways that lose the object type
When it happens
Trigger: Passing a remote_state that is not a RelationConfig object — e.g. a primitive, list, or an unrelated object type — to the BigQuery changeset call.
Common situations: Hand-built remote state dicts in macros, passing the describe results object of a different adapter, or serialization round-trips that convert the RelationConfig into a plain value.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- get_csv_data: argument must be an AgateTable
- remote_state cannot be None
- name attribute must be a string
- {type(df)} is not a supported type for dbt Python materializ
- In adapter.dispatch, got a macro name of "{macro_name}", but
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/ec97085462622e41.
Report an issue: GitHub.