risingwavelabs/risingwave · error

internal error: entered unreachable code

Error message

internal error: entered unreachable code

What it means

`NoShareNode` is a placeholder type used for plan conventions that do not support sharing (Common Subplan Elimination). Its `share_id` is `unreachable!()`: calling it panics with "internal error: entered unreachable code". It means code asked a convention that has no share support for a share id, which should be impossible if the optimizer only queries share_id on share-capable conventions.

Source

Thrown at src/frontend/src/optimizer/plan_node/mod.rs:89

    type PlanNodeType;

    fn as_share(plan: &Self::PlanRefDyn) -> Option<&Self::ShareNode>;
}

pub trait ShareNode<C: ConventionMarker>:
    AnyPlanNodeMeta<C> + PlanTreeNodeUnary<C> + 'static
{
    fn share_id(&self) -> ShareId;
    fn new_share(share: generic::Share<PlanRef<C>>) -> PlanRef<C>;
    fn replace_input(&self, plan: PlanRef<C>) -> PlanRef<C>;
    fn fork_with_input(&self, plan: PlanRef<C>) -> PlanRef<C>;
}

pub struct NoShareNode<C: ConventionMarker>(!, PhantomData<C>);

impl<C: ConventionMarker> ShareNode<C> for NoShareNode<C> {
    fn share_id(&self) -> ShareId {
        unreachable!()
    }

    fn new_share(_plan: generic::Share<PlanRef<C>>) -> PlanRef<C> {
        unreachable!()
    }

    fn replace_input(&self, _plan: PlanRef<C>) -> PlanRef<C> {
        unreachable!()
    }

    fn fork_with_input(&self, _plan: PlanRef<C>) -> PlanRef<C> {
        unreachable!()
    }
}

impl<C: ConventionMarker> PlanTreeNodeUnary<C> for NoShareNode<C> {
    fn input(&self) -> PlanRef<C> {
        unreachable!()

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Only call `share_id()` on nodes/conventions where the ShareNode trait is implemented by a real share type, not NoShareNode.
  2. Gate share-specific optimizer logic behind a capability check or trait bound that excludes NoShareNode conventions.
  3. If you need sharing for a new convention, implement a real ShareNode instead of using NoShareNode.

Example fix

// before
let id = plan.share_id();
// after
if let Some(share) = plan.as_logical_share() {
    let id = share.share_id();
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Rust: only query share_id on share-capable conventions
if plan.as_logical_share().is_some() { /* safe to call share_id */ }

Type guard

fn has_share_support<C: ConventionMarker>(_p: &PlanRef<C>) -> bool { !std::any::TypeId::of::<C::ShareNode>().implements::<NoShareNode>() /* or a capability const */ }

Try / catch

// Rust panics abort the thread; avoid by gating calls.
if let Some(share) = plan.as_logical_share() { let id = share.share_id(); }

Prevention

When it happens

Trigger: Invoking `share_id()` on a `PlanRef` whose convention resolves to `NoShareNode` (e.g. batch or other non-share conventions); generic optimizer code that unconditionally calls `share_id` without checking that the convention supports shares.

Common situations: Adding a generic pass that iterates all plan nodes and calls share_id; incorrectly wiring a convention's ShareNode impl to NoShareNode; refactoring conventions and forgetting to gate share-specific logic.

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 risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/14a3583c890da0b0. Report an issue: GitHub.