dbt-labs/dbt-core · error
string should have a size
Error message
string should have a size
What it means
In `Column::data_type`, when a column's core type is a string type, the code assumes `string_size()` always returns Some and unwraps it with `expect("string should have a size")`. This panics at runtime when a string-typed column has no recorded size (None), i.e. an internal invariant violation rather than a handled error.
Solutions
- Ensure the column has a string size before rendering the type: provide `varchar(n)`/sized string types in DDL or fix upstream metadata so `string_size()` is populated.
- At the call site, replace the `expect` with a fallback that omits the size: `string_type(self.string_size().map(|s| s as usize))` so unsized strings render without a length.
- If constructing Columns manually, always set numeric_precision/string size fields for string dtypes.
Example fix
// before
self.as_static().string_type(Some(self.string_size().expect("string should have a size") as usize))
// after
self.as_static().string_type(self.string_size().map(|s| s as usize)) Defensive patterns
Strategy: validation
Validate before calling
if col.is_string() {
debug_assert!(col.string_size().is_some(), "string column {:?} missing size", col.core_dtype);
}
// guard before calling data_type():
fn safe_data_type(col: &Column) -> String {
if col.is_string() && col.string_size().is_none() { return col.core_dtype.to_string(); }
col.data_type()
} Type guard
fn has_string_size(col: &Column) -> bool {
!col.is_string() || col.string_size().is_some()
} Try / catch
// Rust panics are not catchable via Result; use std::panic::catch_unwind only as a last resort
let dt = std::panic::catch_unwind(|| col.data_type())
.unwrap_or_else(|_| col.core_dtype.to_string()); Prevention
- Always specify a length for string columns (varchar(n)) in DDL
- Check warehouse/driver metadata for null character_maximum_length before type rendering
- Prefer Option-aware rendering over expect/unwrap when extending this code
When it happens
Trigger: Calling `data_type()`/`expanded_data_type()` on a column whose `core_dtype` classifies as string (via `is_string()`) but whose `string_size()` is None — e.g. a string column built from introspection metadata lacking a character maximum length, or a manually constructed Column with a string dtype but no size.
Common situations: Adapters over warehouses that report string columns without a length (e.g. types like TEXT/VARCHAR without limits, BigQuery STRING, or driver metadata missing `character_maximum_length`); user-supplied column definitions like `varchar` with no `(n)`; schema from `DESCRIBE`/information_schema where size fields are null.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Adapter must be configured for the parse phase
- Adapter should be available during parse phase
- agate_table
- Athena
- Datafusion
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/358638aeea208f97.
Report an issue: GitHub.
Appendix: source
Thrown at crates/dbt-adapter/src/column/types.rs:1034
format!("{} {field_type}", col.as_static().quote(f.name()))
})
.collect::<Vec<_>>()
.join(", ");
format!("STRUCT<{fields_str}>")
};
if matches!(col.mode(), BigqueryColumnMode::Repeated) {
format!("ARRAY<{base}>")
} else {
base
}
}
bigquery_data_type_inner(self)
}
_ => {
if self.is_string() {
self.as_static().string_type(Some(
self.string_size().expect("string should have a size") as usize,
))
} else if self.is_numeric() {
self.as_static().numeric_type(
&self.core_dtype,
self.numeric_precision,
self.numeric_scale,
)
} else {
// TODO for types such as Snowflake TIMESTAMP_LTZ(6), we should return ``format!("{}({})", dtype, precision)``.
// Note that this would not be dbt core compatible behavior, but a more correct one.
// Otherwise we may create/alter a table to a wrong type.
// See also https://github.com/dbt-labs/fs/pull/3585#discussion_r2112390711
self.core_dtype.to_string()
}
}
}
}
View on GitHub (pinned to 0267ce9170)