risingwavelabs/risingwave · error

Unspecified window function type

Error message

Unspecified window function type

What it means

WindowFuncKind::from_protobuf maps a protobuf GeneralType to a window function kind. If the general type is Unspecified, the kind is unknown and the conversion fails rather than defaulting to some function.

Source

Thrown at src/expr/core/src/window_function/kind.rs:49

    DenseRank,
    Lag,
    Lead,

    // Aggregate functions that are used with `OVER`.
    #[display("{0}")]
    Aggregate(AggType),
}

impl WindowFuncKind {
    pub fn from_protobuf(
        window_function_type: &risingwave_pb::expr::window_function::PbType,
    ) -> Result<Self> {
        use risingwave_pb::expr::agg_call::PbKind as PbAggKind;
        use risingwave_pb::expr::window_function::{PbGeneralType, PbType};

        let kind = match window_function_type {
            PbType::General(typ) => match PbGeneralType::try_from(*typ) {
                Ok(PbGeneralType::Unspecified) => bail!("Unspecified window function type"),
                Ok(PbGeneralType::RowNumber) => Self::RowNumber,
                Ok(PbGeneralType::Rank) => Self::Rank,
                Ok(PbGeneralType::DenseRank) => Self::DenseRank,
                Ok(PbGeneralType::Lag) => Self::Lag,
                Ok(PbGeneralType::Lead) => Self::Lead,
                Err(_) => bail!("no such window function type"),
            },
            #[expect(deprecated)]
            PbType::Aggregate(kind) => Self::Aggregate(AggType::from_protobuf_flatten(
                PbAggKind::try_from(*kind).context("no such aggregate function type")?,
                None,
                None,
            )?),
            PbType::Aggregate2(agg_type) => Self::Aggregate(AggType::from_protobuf(agg_type)?),
        };
        Ok(kind)
    }
}

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Set the general window function type explicitly (RowNumber, Rank, DenseRank, Lag, Lead) in the frontend when building the plan.
  2. Check for frontend/meta version skew where the proto type field is not populated.
  3. Verify the generated prost enum from the .proto file matches the sender's version.

Example fix

// before
window_function.set_general_type(PbGeneralType::Unspecified);
// after
window_function.set_general_type(PbGeneralType::RowNumber);
Defensive patterns

Strategy: validation

Validate before calling

fn window_kind_is_set(t: &PbGeneralType) -> bool { !matches!(t, PbGeneralType::Unspecified) }

Type guard

fn is_known_general_type(t: PbGeneralType) -> bool {
    matches!(t, PbGeneralType::RowNumber | PbGeneralType::Rank | PbGeneralType::DenseRank | PbGeneralType::Lag | PbGeneralType::Lead)
}

Try / catch

let kind = match WindowFuncKind::from_protobuf(&pb) {
    Ok(k) => k,
    Err(e) => return Err(anyhow!("plan contains unnamed window function: {}", e)),
};

Prevention

When it happens

Trigger: Deserializing a WindowFunction whose PbType::General carries PbGeneralType::Unspecified — i.e., the general window function (RowNumber/Rank/DenseRank/Lag/Lead) was never named in the plan.

Common situations: Frontend bug or older proto version that left the general type unset; hand-assembled protobuf test messages missing the type field.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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