{"record":{"id":"358638aeea208f97","repo":"dbt-labs/dbt-core","slug":"string-should-have-a-size","errorCode":null,"errorMessage":"string should have a size","messagePattern":"string should have a size","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-adapter/src/column/types.rs","lineNumber":1034,"sourceCode":"                                format!(\"{} {field_type}\", col.as_static().quote(f.name()))\n                            })\n                            .collect::<Vec<_>>()\n                            .join(\", \");\n                        format!(\"STRUCT<{fields_str}>\")\n                    };\n\n                    if matches!(col.mode(), BigqueryColumnMode::Repeated) {\n                        format!(\"ARRAY<{base}>\")\n                    } else {\n                        base\n                    }\n                }\n                bigquery_data_type_inner(self)\n            }\n            _ => {\n                if self.is_string() {\n                    self.as_static().string_type(Some(\n                        self.string_size().expect(\"string should have a size\") as usize,\n                    ))\n                } else if self.is_numeric() {\n                    self.as_static().numeric_type(\n                        &self.core_dtype,\n                        self.numeric_precision,\n                        self.numeric_scale,\n                    )\n                } else {\n                    // TODO for types such as Snowflake TIMESTAMP_LTZ(6), we should return ``format!(\"{}({})\", dtype, precision)``.\n                    //  Note that this would not be dbt core compatible behavior, but a more correct one.\n                    //  Otherwise we may create/alter a table to a wrong type.\n                    //  See also https://github.com/dbt-labs/fs/pull/3585#discussion_r2112390711\n                    self.core_dtype.to_string()\n                }\n            }\n        }\n    }\n","sourceCodeStart":1016,"sourceCodeEnd":1052,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-adapter/src/column/types.rs#L1016-L1052","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nself.as_static().string_type(Some(self.string_size().expect(\"string should have a size\") as usize))\n\n// after\nself.as_static().string_type(self.string_size().map(|s| s as usize))","handlingStrategy":"validation","validationCode":"if col.is_string() {\n    debug_assert!(col.string_size().is_some(), \"string column {:?} missing size\", col.core_dtype);\n}\n// guard before calling data_type():\nfn safe_data_type(col: &Column) -> String {\n    if col.is_string() && col.string_size().is_none() { return col.core_dtype.to_string(); }\n    col.data_type()\n}","typeGuard":"fn has_string_size(col: &Column) -> bool {\n    !col.is_string() || col.string_size().is_some()\n}","tryCatchPattern":"// Rust panics are not catchable via Result; use std::panic::catch_unwind only as a last resort\nlet dt = std::panic::catch_unwind(|| col.data_type())\n    .unwrap_or_else(|_| col.core_dtype.to_string());","preventionTips":["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"],"tags":["panic","unwrap","rust","adapter","column-type"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}