prestodb/presto · critical · PrestoException
GENERIC_INTERNAL_ERROR
GENERIC_INTERNAL_ERROR
Error message
ConnectorMetadata getCommonPartitioningHandle() is implemented without getAlternativeLayout()
What it means
getAlternativeLayoutHandle() defaults to throwing GENERIC_INTERNAL_ERROR with this message. The contract is that if a connector implements getCommonPartitioningHandle() (promising it can transparently convert layout handles to a common partitioning), it must also implement getAlternativeLayoutHandle(). Hitting the default means the connector broke that contract, so the engine reports it as an internal error.
Source
Thrown at presto-spi/src/main/java/com/facebook/presto/spi/connector/ConnectorMetadata.java:185
}
else if (layouts.size() > 1) {
throw new PrestoException(NOT_SUPPORTED, "Connector returned multiple layouts for table " + table);
}
return layouts.get(0);
}
ConnectorTableLayout getTableLayout(ConnectorSession session, ConnectorTableLayoutHandle handle);
/**
* Return a table layout handle whose partitioning is converted to the provided partitioning handle,
* but otherwise identical to the provided table layout handle.
* The provided table layout handle must be one that the connector can transparently convert to from
* the original partitioning handle associated with the provided table layout handle,
* as promised by {@link #getCommonPartitioningHandle}.
*/
default ConnectorTableLayoutHandle getAlternativeLayoutHandle(ConnectorSession session, ConnectorTableLayoutHandle tableLayoutHandle, ConnectorPartitioningHandle partitioningHandle)
{
throw new PrestoException(GENERIC_INTERNAL_ERROR, "ConnectorMetadata getCommonPartitioningHandle() is implemented without getAlternativeLayout()");
}
/**
* Experimental: if true, the engine will invoke getLayout otherwise, getLayout will not be called.
*/
@Deprecated
@Experimental
default boolean isLegacyGetLayoutSupported(ConnectorSession session, ConnectorTableHandle tableHandle)
{
return true;
}
/**
* Return a partitioning handle which the connector can transparently convert both {@code left} and {@code right} into.
*/
@Deprecated
default Optional<ConnectorPartitioningHandle> getCommonPartitioningHandle(ConnectorSession session, ConnectorPartitioningHandle left, ConnectorPartitioningHandle right)
{View on GitHub (pinned to 55bb57d202)
Solutions
- Implement getAlternativeLayoutHandle(ConnectorSession, ConnectorTableLayoutHandle, ConnectorPartitioningHandle) in the connector to translate the layout handle to the common partitioning
- If the connector cannot actually convert handles, remove/fix the getCommonPartitioningHandle implementation so it no longer promises common partitioning
- Report as a connector bug if using a third-party connector
Example fix
// before: only getCommonPartitioningHandle overridden
// after
@Override
public ConnectorTableLayoutHandle getAlternativeLayoutHandle(ConnectorSession session, ConnectorTableLayoutHandle handle, ConnectorPartitioningHandle partitioningHandle) {
return ((MyLayoutHandle) handle).withPartitioning((MyPartitioningHandle) partitioningHandle);
} Defensive patterns
Strategy: validation
Validate before calling
// connector self-check: the pair must be implemented together
@Override
public ConnectorPartitioningHandle getCommonPartitioningHandle(ConnectorSession session, ConnectorPartitioningHandle left, ConnectorPartitioningHandle right) {
if (getClass().getMethod("getAlternativeLayoutHandle", ConnectorSession.class, ConnectorTableLayoutHandle.class, ConnectorPartitioningHandle.class)
.getDeclaringClass() == ConnectorMetadata.class) {
throw new IllegalStateException("getCommonPartitioningHandle requires getAlternativeLayoutHandle");
}
return super.getCommonPartitioningHandle(session, left, right);
} Try / catch
try {
return metadata.getAlternativeLayoutHandle(session, layoutHandle, partitioningHandle);
} catch (PrestoException e) {
if (e.getErrorCode() == StandardErrorCode.GENERIC_INTERNAL_ERROR.toErrorCodeCode()) {
throw new IllegalStateException("Connector contract violation: getCommonPartitioningHandle without getAlternativeLayoutHandle", e);
}
throw e;
} Prevention
- Whenever implementing getCommonPartitioningHandle, implement getAlternativeLayoutHandle in the same change
- Add a connector unit test exercising the alternative-layout path
- Review connector upgrades for partially implemented partitioning contracts
When it happens
Trigger: The engine's newTableLayoutHandle path calls getAlternativeLayoutHandle on a connector that implements getCommonPartitioningHandle but not getAlternativeLayoutHandle; the default throws GENERIC_INTERNAL_ERROR.
Common situations: Custom connector development where getCommonPartitioningHandle was implemented (e.g. for CTE/writer repartitioning) but the companion getAlternativeLayoutHandle was forgotten; upgrading a connector partially.
Related errors
- GENERIC_INTERNAL_ERROR
- ARROW_INTERNAL_ERROR
- GENERIC_INTERNAL_ERROR
- NOT_SUPPORTED
- HUDI_INVALID_PARTITION_VALUE
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/e8b5cfb2e4c157ff.
Report an issue: GitHub.