databendlabs/databend · error

internal error: entered unreachable code

Error message

internal error: entered unreachable code

What it means

While building nested column name paths for deserializing parquet chunks (used by virtual columns / nested data), the code walks a type tree and expects every step to be a nested struct/fields node; any other DataType at an intermediate step hits unreachable!. Means the recorded index path does not match the actual type tree of the block schema.

Solutions

  1. Refresh virtual column metadata for the affected table (drop and recompute virtual columns)
  2. Verify the table schema matches the schema recorded in the segment; restore schema from a snapshot if it drifted
  3. Retry with virtual columns disabled to isolate the issue
  4. File a bug with the table schema and segment info if it happens on an unmodified table

Example fix

// before
_ => unreachable!(),
// after
other => {
    return Err(ErrorCode::StorageOther(format!(
        "unexpected type {other:?} while resolving column name path at index {idx}"
    )));
}
Defensive patterns

Strategy: validation

Validate before calling

// rust: verify index path matches nested schema before deserialization
fn path_matches_schema(schema: &DataType, path: &[usize]) -> bool {
    let mut ty = schema;
    for i in path {
        match ty {
            DataType::Tuple(fields) if *i < fields.len() => ty = &fields[*i],
            _ => return false,
        }
    }
    true
}

Type guard

fn is_nested_at(ty: &DataType, idx: usize) -> bool {
    matches!(ty, DataType::Tuple(fields) if idx < fields.len())
}

Prevention

When it happens

Trigger: deserialize_parquet_columns walks a virtual-column index path into a schema where a step resolves to a non-nested type (e.g. leaf instead of Tuple/struct fields) — schema/type mismatch between stored virtual column info and current schema.

Common situations: Tables with virtual columns whose schema changed (ALTER dropping/renesting columns); segments written before/after a schema change; hand-edited or legacy virtual column metadata.

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 databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/152b3e5fe15570af. Report an issue: GitHub.

Appendix: source

Thrown at src/query/storages/fuse/src/io/read/block/parquet/mod.rs:206

        Projection::InnerColumns(path_indices) => {
            let mut name_paths = Vec::with_capacity(path_indices.len());
            for index_path in path_indices.values() {
                let mut name_path = Vec::with_capacity(index_path.len());
                let first_index = index_path[0];
                name_path.push(schema.fields[first_index].name().to_string());
                let mut idx = 1;
                let mut ty = schema.fields[first_index].data_type().clone();
                while idx < index_path.len() {
                    match ty.remove_nullable() {
                        TableDataType::Tuple {
                            fields_name,
                            fields_type,
                        } => {
                            let next_index = index_path[idx];
                            name_path.push(fields_name[next_index].clone());
                            ty = fields_type[next_index].clone();
                        }
                        _ => unreachable!(),
                    }
                    idx += 1;
                }
                name_paths.push(name_path);
            }
            name_paths
        }
    }
}

View on GitHub (pinned to 288d84d76e)