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
- Inspect the optimizer/rewriter rule that produced the malformed LimitNode and fix child list construction.
- Capture the query and stack trace and file an issue — this is an internal invariant violation.
- Try disabling the suspected optimization rule as a workaround.
- 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
- Always pass exactly one source child when constructing/replacing LimitNode children.
- Keep custom optimizer rules updated against engine plan-shape contracts.
- Report internal invariant failures with the query plan to maintainers.
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
- DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION
- GENERIC_INTERNAL_ERROR
- GENERIC_INTERNAL_ERROR
- FUNCTION_IMPLEMENTATION_ERROR
- GENERIC_INTERNAL_ERROR
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/c5525b38d073cda8.
Report an issue: GitHub.