risingwavelabs/risingwave · error

Unrecognized agg.

Error message

Unrecognized agg.

What it means

AggType::from_protobuf_flatten converts a protobuf AggKind into the internal AggType. PbAggKind::Unspecified is the protobuf zero-value; encountering it means the sender did not set the agg kind field (or sent a corrupt/default message), so the parser cannot determine which aggregate to build and bails with "Unrecognized agg."

Solutions

  1. Ensure the plan builder sets the agg_kind field explicitly to a valid PbAggKind before serializing.
  2. Check for version skew between the component producing the plan and the one consuming it; align versions.
  3. Validate the generated plan protobuf (e.g. with prost validation or a unit test) that agg_kind != Unspecified.

Example fix

// before
let node = PbAggNode { agg_calls: vec![PbAggCall { .., /* agg_kind omitted */ }] };
// after
let node = PbAggNode { agg_calls: vec![PbAggCall { .., agg_kind: PbAggKind::Sum as i32 }] };
Defensive patterns

Strategy: validation

Validate before calling

// before sending plan protobuf
for (const call of aggNode.agg_calls) {
  if (call.agg_kind === PbAggKind.Unspecified) throw new Error("agg_kind must be set");
}

Type guard

function hasAggKind(call) { return call.agg_kind !== undefined && call.agg_kind !== PbAggKind.Unspecified; }

Try / catch

match AggType::from_protobuf_flatten(&pb) {
    Ok(agg) => agg,
    Err(e) if e.to_string().contains("Unrecognized agg") => bail!("plan produced unset agg_kind; check plan builder version"),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Deserializing an Aggregate protocol buffer whose agg_kind field is left Unspecified — e.g. a hand-built PbAggNode without setting kind, a schema/version mismatch where the kind field was dropped, or serialization bugs upstream.

Common situations: Writing plan protobufs by hand or via codegen and forgetting to set agg_kind; cross-version plan exchange where a newer kind is unknown to the older binary and defaults to Unspecified; corrupted plan fragments.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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

Appendix: source

Thrown at src/expr/core/src/aggregate/def.rs:276

    }
}

impl AggType {
    pub fn from_protobuf_flatten(
        pb_kind: PbAggKind,
        user_defined: Option<&PbUserDefinedFunctionMetadata>,
        scalar: Option<&PbExprNode>,
    ) -> Result<Self> {
        match pb_kind {
            PbAggKind::UserDefined => {
                let user_defined = user_defined.context("expect user defined")?;
                Ok(AggType::UserDefined(user_defined.clone()))
            }
            PbAggKind::WrapScalar => {
                let scalar = scalar.context("expect scalar")?;
                Ok(AggType::WrapScalar(scalar.clone()))
            }
            PbAggKind::Unspecified => bail!("Unrecognized agg."),
            _ => Ok(AggType::Builtin(pb_kind)),
        }
    }

    pub fn to_protobuf_simple(&self) -> PbAggKind {
        match self {
            Self::Builtin(pb) => *pb,
            Self::UserDefined(_) => PbAggKind::UserDefined,
            Self::WrapScalar(_) => PbAggKind::WrapScalar,
        }
    }

    pub fn from_protobuf(pb_type: &PbAggType) -> Result<Self> {
        match PbAggKind::try_from(pb_type.kind).context("no such aggregate function type")? {
            PbAggKind::Unspecified => bail!("Unrecognized agg."),
            PbAggKind::UserDefined => Ok(AggType::UserDefined(pb_type.get_udf_meta()?.clone())),
            PbAggKind::WrapScalar => Ok(AggType::WrapScalar(pb_type.get_scalar_expr()?.clone())),
            kind => Ok(AggType::Builtin(kind)),

View on GitHub (pinned to 6469eb736d)