prestodb/presto · error · PrestoException
GENERIC_INTERNAL_ERROR
GENERIC_INTERNAL_ERROR
Error message
Unknown plan phase
What it means
ConnectorPlanOptimizerManager.getOptimizers maps a PlanPhase (LOGICAL or PHYSICAL) to the registered connector optimizer providers. An unknown phase value cannot occur through the enum's normal use, so the default branch throws GENERIC_INTERNAL_ERROR — hitting it means the enum gained a value not handled in the switch, an internal consistency failure.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/planner/ConnectorPlanOptimizerManager.java:61
checkArgument(planOptimizerProviders.putIfAbsent(connectorId, planOptimizerProvider) == null,
"ConnectorPlanOptimizerProvider for connector '%s' is already registered", connectorId);
}
public void removePlanOptimizerProvider(ConnectorId connectorId)
{
requireNonNull(connectorId, "connectorId is null");
planOptimizerProviders.remove(connectorId);
}
public Map<ConnectorId, Set<ConnectorPlanOptimizer>> getOptimizers(PlanPhase phase)
{
switch (phase) {
case LOGICAL:
return ImmutableMap.copyOf(transformValues(planOptimizerProviders, ConnectorPlanOptimizerProvider::getLogicalPlanOptimizers));
case PHYSICAL:
return ImmutableMap.copyOf(transformValues(planOptimizerProviders, ConnectorPlanOptimizerProvider::getPhysicalPlanOptimizers));
default:
throw new PrestoException(GENERIC_INTERNAL_ERROR, "Unknown plan phase " + phase);
}
}
public enum PlanPhase
{
LOGICAL, PHYSICAL
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Update the switch in getOptimizers to handle the new PlanPhase constant
- Ensure all cluster nodes run the same build to avoid enum value skew
- If not modifying Presto, upgrade to a consistent release and report the trigger to maintainers
Example fix
// before
switch (phase) {
case LOGICAL: ...; case PHYSICAL: ...;
default: throw new PrestoException(GENERIC_INTERNAL_ERROR, "Unknown plan phase " + phase);
}
// after
switch (phase) {
case LOGICAL: ...; case PHYSICAL: ...;
case RUNTIME: return ImmutableMap.copyOf(transformValues(planOptimizerProviders, ConnectorPlanOptimizerProvider::getRuntimePlanOptimizers));
default: throw new PrestoException(GENERIC_INTERNAL_ERROR, "Unknown plan phase " + phase);
} Defensive patterns
Strategy: type-guard
Validate before calling
// Exhaustive handling on your side
boolean supported = phase == PlanPhase.LOGICAL || phase == PlanPhase.PHYSICAL;
if (!supported) throw new IllegalArgumentException("Unsupported phase: " + phase); Type guard
boolean isKnownPhase(PlanPhase p) {
return p == PlanPhase.LOGICAL || p == PlanPhase.PHYSICAL;
} Try / catch
try { manager.getOptimizers(phase); } catch (PrestoException e) { if (e.getErrorCode().equals(GENERIC_INTERNAL_ERROR.toErrorCode()) && e.getMessage().startsWith("Unknown plan phase")) { useDefaultOptimizers(); } else throw e; } Prevention
- Never introduce new PlanPhase constants without updating the switch
- Keep all cluster nodes on the same build to avoid enum skew
- Prefer iterating known phases explicitly rather than reflective enum lookups
When it happens
Trigger: Adding a new PlanPhase enum constant without updating getOptimizers' switch; reflective/deserialization code producing a phase outside LOGICAL/PHYSICAL; called from PlanOptimizers during plan optimization setup.
Common situations: Custom forks of Presto extending PlanPhase; partial upgrades where compiled classes disagree on enum values (mixed coordinator/worker builds).
Related errors
- unexpected update mode:
- GENERIC_INTERNAL_ERROR
- GENERIC_INTERNAL_ERROR
- GENERIC_INTERNAL_ERROR
- GENERIC_INTERNAL_ERROR
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/c7615e3eaf85a129.
Report an issue: GitHub.