pola-rs/polars · error
{}
Error message
{} What it means
accumulate_dataframes_vertical_unchecked stacks DataFrames vertically without checking schema compatibility, but it does check that all frames have the same width. When a subsequent frame's width differs from the accumulated one, it panics with the width_mismatch message. 'Unchecked' means column names/dtypes are not validated — only width.
Solutions
- Ensure all input DataFrames have the same number of columns before calling (pad with nulls or drop extra columns)
- When reading heterogeneous files, use explicit schema overrides / a unified schema (e.g. hive/partitioned scan schemas) so every fragment yields the same width
- Use the checked accumulate_dataframes_vertical (or lazy concat with 'diagonal'/'vertical_relaxed' how) instead of the _unchecked variant
- Log/print each df.width() in the iterator to find which frame diverges
Example fix
// before
let df = accumulate_dataframes_vertical_unchecked(frames);
// after
let width = frames.peek().map(|f| f.width());
let frames = frames.map(|f| if f.width() == width { f } else { fix_or_pad(f) });
let df = accumulate_dataframes_vertical_unchecked(frames); Defensive patterns
Strategy: validation
Validate before calling
let widths: Vec<usize> = frames.iter().map(|f| f.width()).collect();
if !widths.iter().all(|w| *w == widths[0]) {
panic!("frame widths differ: {:?}", widths);
} Try / catch
match std::panic::catch_unwind(|| accumulate_dataframes_vertical_unchecked(frames.clone())) {
Ok(df) => df,
Err(_) => accumulate_dataframes_vertical(frames), // checked variant
} Prevention
- Use accumulate_dataframes_vertical (checked) unless profiling proves the unchecked one matters
- Use lazy concat with how='diagonal' or 'vertical_relaxed' for heterogeneous sources
- Enforce a unified schema when scanning multiple files/partitions
When it happens
Trigger: Passing an iterator of DataFrames with differing column counts to accumulate_dataframes_vertical_unchecked; called from scan/read/execution paths (finish, finish_reader, execute_chunks, chunk_df_for_writing) when file/fragment schemas disagree.
Common situations: Reading multiple CSV/parquet files with different numbers of columns through one scan; schema drift between partitions; a projection changing width mid-iteration; concatenating frames where a select dropped a column.
Related errors
- DataFrame `how` must be one of
- `strict` cannot be used with `how='horizontal_extend'`
- {0}
- activate dtype
- activate dtype-categorical to convert dictionary arrays
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/6aca71cd15a4c3f4.
Report an issue: GitHub.
Appendix: source
Thrown at crates/polars-core/src/utils/mod.rs:870
df1.width(),
df2.width(),
)
}
/// This takes ownership of the DataFrame so that drop is called earlier.
/// Does not check if schema is correct
pub fn accumulate_dataframes_vertical_unchecked<I>(dfs: I) -> DataFrame
where
I: IntoIterator<Item = DataFrame>,
{
let mut iter = dfs.into_iter();
let additional = iter.size_hint().0;
let mut acc_df = iter.next().unwrap();
acc_df.reserve_chunks(additional);
for df in iter {
if acc_df.width() != df.width() {
panic!("{}", width_mismatch(&acc_df, &df));
}
acc_df.vstack_mut_owned_unchecked(df);
}
acc_df
}
/// This takes ownership of the DataFrame so that drop is called earlier.
/// # Panics
/// Panics if `dfs` is empty.
pub fn accumulate_dataframes_vertical<I>(dfs: I) -> PolarsResult<DataFrame>
where
I: IntoIterator<Item = DataFrame>,
{
let mut iter = dfs.into_iter();
let additional = iter.size_hint().0;
let mut acc_df = iter.next().unwrap();
acc_df.reserve_chunks(additional);View on GitHub (pinned to fe841f959e)