risingwavelabs/risingwave · error

expect vector column but got

Error message

expect vector column but got: {:?}

What it means

The vector index write executor validates that the index column's data type is `DataType::Vector(dimension)`. If the retrieved index column type is not a vector type, it bails with 'expect vector column but got: {type}', meaning the index write's schema doesn't match a vector index.

Solutions

  1. Ensure the column used in the vector index is declared as `VECTOR(dim)`.
  2. Recreate the index on a column with the correct vector type.
  3. Re-run the DDL; if it persists, check for plan/proto mismatches and report a bug.
  4. Verify upstream MV/schema wasn't altered incompatibly.

Example fix

// before
CREATE INDEX ON t (embedding_text);
// after
CREATE INDEX ON t USING hnsw (embedding vector_cosine_ops);
Defensive patterns

Strategy: type-guard

Validate before calling

-- the indexed column must be VECTOR type
SELECT data_type FROM information_schema.columns WHERE table_name='t' AND column_name='embedding';

Type guard

fn is_vector(t: &DataType) -> bool { matches!(t, DataType::Vector(_)) }

Prevention

When it happens

Trigger: Building a vector-index write executor (stream plan for writing into a vector index) where the index column type resolved from the proto is not `DataType::Vector` — e.g. a non-vector column wired as the index column or a corrupted/mismatched plan.

Common situations: Running an `CREATE INDEX ... USING hnsw`-style flow where the indexed column isn't of vector type; internal plan/proto inconsistencies after schema changes.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/ae162fa6645babb6. Report an issue: GitHub.

Appendix: source

Thrown at src/stream/src/from_proto/vector_index_write.rs:51

        params: ExecutorParams,
        node: &Self::Node,
        store: impl StateStore,
    ) -> StreamResult<Executor> {
        let [input]: [_; 1] = params.input.try_into().unwrap();

        let table = node.table.as_ref().unwrap();
        assert_eq!(table.columns.len(), input.schema().len());
        let index_col_type = DataType::from(
            table.columns[0]
                .column_desc
                .as_ref()
                .unwrap()
                .column_type
                .as_ref()
                .unwrap(),
        );
        let DataType::Vector(dimension) = &index_col_type else {
            bail!("expect vector column but got: {:?}", index_col_type)
        };
        let DataType::Vector(input_dimension) = &input.schema().fields[0].data_type else {
            bail!(
                "expect first input vector column but got: {:?}",
                index_col_type
            )
        };
        assert_eq!(dimension, input_dimension);

        let executor = VectorIndexWriteExecutor::new(input, store, table.id).await?;
        Ok(Executor::new(params.info, Box::new(executor)))
    }
}

View on GitHub (pinned to 6469eb736d)