prestodb/presto · critical · PrestoException

GENERIC_INTERNAL_ERROR

GENERIC_INTERNAL_ERROR

Error message

Expect exactly 1 child PlanNode

What it means

LimitNode enforces its plan-shape invariant (exactly one source child) via checkCondition, which throws PrestoException with GENERIC_INTERNAL_ERROR when violated. This is an engine-internal invariant failure, not user input error: the LimitNode was constructed or its children were replaced with a list whose size is not 1.

Source

Thrown at presto-spi/src/main/java/com/facebook/presto/spi/plan/LimitNode.java:149

    }

    @Override
    public PlanNode assignStatsEquivalentPlanNode(Optional<PlanNode> statsEquivalentPlanNode)
    {
        return new LimitNode(getSourceLocation(), getId(), statsEquivalentPlanNode, source, count, getStep());
    }

    @Override
    public PlanNode replaceChildren(List<PlanNode> newChildren)
    {
        checkCondition(newChildren != null && newChildren.size() == 1, GENERIC_INTERNAL_ERROR, "Expect exactly 1 child PlanNode");
        return new LimitNode(getSourceLocation(), getId(), getStatsEquivalentPlanNode(), newChildren.get(0), count, getStep());
    }

    private static void checkCondition(boolean condition, ErrorCodeSupplier errorCode, String message)
    {
        if (!condition) {
            throw new PrestoException(errorCode, message);
        }
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Inspect the optimizer/rewriter rule that produced the malformed LimitNode and fix child list construction.
  2. Capture the query and stack trace and file an issue — this is an internal invariant violation.
  3. Try disabling the suspected optimization rule as a workaround.
  4. Upgrade to a Presto version where the planner bug is fixed.

Example fix

// before
node.replaceChildren(children); // children may be empty

// after
checkState(children.size() == 1, "LimitNode requires exactly 1 child, got %s", children.size());
node.replaceChildren(ImmutableList.of(children.get(0)));
Defensive patterns

Strategy: try-catch

Try / catch

try {
    plan = planOptimizers.optimize(plan);
} catch (PrestoException e) {
    if (e.getErrorCode().getCode() == GENERIC_INTERNAL_ERROR.toErrorCode().getCode()) {
        log.error("Planner invariant violated for query " + queryId, e);
        throw e; // report bug; not user-fixable
    } else throw e;
}

Prevention

When it happens

Trigger: Building a LimitNode with newChildren.size() != 1, or replaceChildren(LimitNode) receiving an empty or multi-element list from a plan rewriter/optimizer rule.

Common situations: Custom PlanNode rewriters/optimizers that mishandle child replacement; engine bug after upgrades; tests constructing malformed plans.

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 prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/c5525b38d073cda8. Report an issue: GitHub.