dbt-labs/dbt-core · error · minijinja::Error::InvalidOperation
show_tables_results must contain AgateTables
Error message
show_tables_results must contain AgateTables
What it means
`build_catalog_from_show_tables_and_svv_columns` iterates the `show_tables_results` argument expecting every element to be an AgateTable. This error is thrown when any element of that iterable cannot be downcast to `Arc<AgateTable>`. It protects the catalog builder from receiving dicts or other serialized data in the show-tables list.
Source
Thrown at crates/dbt-adapter/src/adapter/mod.rs:560
/// ```
#[tracing::instrument(skip_all, level = "trace")]
pub fn build_catalog_from_show_tables_and_svv_columns(
&self,
_state: &State,
args: &[Value],
) -> Result<Value, minijinja::Error> {
match &self.inner {
Typed { adapter, .. } => {
let iter = ArgsIter::new(
"build_catalog_from_show_tables_and_svv_columns",
&["show_tables_results", "svv_columns"],
args,
);
let show_tables_value = iter.next_arg::<&Value>()?;
let mut show_tables_results: Vec<Arc<AgateTable>> = Vec::new();
for table_value in show_tables_value.try_iter()? {
let table = table_value.downcast_object::<AgateTable>().ok_or_else(|| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
"show_tables_results must contain AgateTables",
)
})?;
show_tables_results.push(table);
}
let svv_columns = iter
.next_arg::<&Value>()?
.downcast_object::<AgateTable>()
.ok_or_else(|| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
"svv_columns must be an AgateTable",
)
})?;
iter.finish()?;
let catalog = adapter.build_catalog_from_show_tables_and_svv_columns(View on GitHub (pinned to 0267ce9170)
Solutions
- Ensure each entry in show_tables_results is converted via load_agate_table()/AgateTable before being passed
- Check that the list is not accidentally a single table wrapped in the wrong nesting level (e.g. list of dicts instead of list of tables)
- Log the element type at the failing index to confirm which item is not an AgateTable
Example fix
// before show_tables_results = res['tables'] # list of dicts // after show_tables_results = [load_agate_table(t) for t in res['tables']]
Defensive patterns
Strategy: validation
Validate before calling
# ensure every element is an agate table before the call assert all(hasattr(t, 'column_names') for t in show_tables_results), 'every show_tables_result must be an agate Table'
Type guard
fn all_agate_tables(v: &Value) -> bool {
v.try_iter().map(|it| it.all(|x| x.downcast_object::<AgateTable>().is_some())).unwrap_or(false)
} Try / catch
match table_value.downcast_object::<AgateTable>() {
Some(t) => show_tables_results.push(t),
None => return Err(minijinja::Error::new(minijinja::ErrorKind::InvalidOperation,
"show_tables_results must contain AgateTables; convert each item with load_agate_table()")),
} Prevention
- Convert each show-tables result set to an AgateTable at collection time
- Test custom catalog macros against the built-in macro output shape
- Avoid mixing raw dicts and parsed tables in the results list
When it happens
Trigger: Calling build_catalog_from_show_tables_and_svv_columns with a show_tables_results list that contains non-AgateTable items — e.g. plain dicts from a custom `show_tables` macro or a partially serialized results array.
Common situations: Redshift catalog ingestion where a custom show-tables override returns raw rows; mixing parsed and unparsed result sets when assembling the catalog arguments from Python.
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
- svv_columns must be an AgateTable
- grants_table must be an AgateTable
- agate_table must be an AgateTable
- list_relations_schemas_by_patterns for Redshift
- ColumnsAsTuple::count_occurrences_of
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/4f261ed8359036fe.
Report an issue: GitHub.