{"record":{"id":"672da95920bd89cc","repo":"prestodb/presto","slug":"generic-internal-error-672da9","errorCode":"GENERIC_INTERNAL_ERROR","errorMessage":"Cannot assign canonical plan id to Canonical table scan node: %s","messagePattern":"Cannot assign canonical plan id to Canonical table scan node: (.+?)","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/sql/planner/CanonicalTableScanNode.java","lineNumber":102,"sourceCode":"\n    @Override\n    @JsonProperty\n    public List<VariableReferenceExpression> getOutputVariables()\n    {\n        return outputVariables;\n    }\n\n    @Override\n    public PlanNode replaceChildren(List<PlanNode> newChildren)\n    {\n        checkArgument(newChildren.isEmpty(), \"newChildren is not empty\");\n        return this;\n    }\n\n    @Override\n    public PlanNode assignStatsEquivalentPlanNode(Optional<PlanNode> statsEquivalentPlanNode)\n    {\n        throw new PrestoException(GENERIC_INTERNAL_ERROR, format(\"Cannot assign canonical plan id to Canonical table scan node: %s\", this));\n    }\n\n    @JsonProperty\n    public CanonicalTableHandle getTable()\n    {\n        return table;\n    }\n\n    @JsonProperty\n    public Map<VariableReferenceExpression, ColumnHandle> getAssignments()\n    {\n        return assignments;\n    }\n\n    @Override\n    public <R, C> R accept(InternalPlanVisitor<R, C> visitor, C context)\n    {\n        return visitor.visitCanonicalTableScan(this, context);","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/sql/planner/CanonicalTableScanNode.java#L84-L120","documentation":"Like CanonicalJoinNode, a CanonicalTableScanNode cannot be assigned a stats-equivalent plan node id; doing so breaks canonical-planner invariants and throws GENERIC_INTERNAL_ERROR. Canonical table scans are placeholders, so stats-equivalence bookkeeping must target the real node.","triggerScenarios":"Internal planner flow where assignStatsEquivalentPlanNode(Optional.of(node)) is called on a CanonicalTableScanNode during canonical plan generation or stats extraction.","commonSituations":"Engine bugs with canonical plan stats collection (e.g. EXPLAIN with stats, cost-based optimization paths); custom rules or extensions mishandling canonical wrappers; recent version upgrades exposing new plan shapes.","solutions":["File the issue with the stack trace and plan — this is an internal invariant violation, not user error","Upgrade Presto to a version with the canonical-plan stats fix","In custom code, dereference the wrapped source node before recording stats equivalence"],"exampleFix":"// before\ncanonicalTableScan.assignStatsEquivalentPlanNode(Optional.of(equivalentNode));\n// after\nPlanNode target = canonicalTableScan.getSource(); // real scan node\ntarget.assignStatsEquivalentPlanNode(Optional.of(equivalentNode));","handlingStrategy":"try-catch","validationCode":"if (node instanceof CanonicalTableScanNode) {\n    throw new IllegalStateException(\"Assign stats-equivalent id to the wrapped scan node, not the canonical wrapper\");\n}","typeGuard":"boolean isCanonicalWrapper(PlanNode n) {\n    return n instanceof CanonicalTableScanNode || n instanceof CanonicalJoinNode;\n}","tryCatchPattern":"try { planner.plan(...); } catch (PrestoException e) { if (e.getErrorCode().equals(GENERIC_INTERNAL_ERROR.toErrorCode()) && e.getMessage().contains(\"Canonical table scan node\")) { reportInternalBug(e); } else throw e; }","preventionTips":["Do not invoke assignStatsEquivalentPlanNode on CanonicalTableScanNode","Dereference to the underlying table scan for stats mapping","Report stack traces upstream — user code should never reach this path"],"tags":["planner","internal-error","canonical-plan"],"backgroundTag":"presto-internal-invariant-violation","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}