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

  1. 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.
  2. 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.
  3. 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

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


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)