{"record":{"id":"a3a292b3d12b4497","repo":"prestodb/presto","slug":"unsupported-frame-end-type","errorCode":null,"errorMessage":"Unsupported frame end type: ","messagePattern":"Unsupported frame end type: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/operator/window/WindowPartition.java","lineNumber":392,"sourceCode":"\n        int frameEnd;\n        switch (frameInfo.getEndType()) {\n            case UNBOUNDED_FOLLOWING:\n                frameEnd = partitionEnd - partitionStart - 1;\n                break;\n            case CURRENT_ROW:\n                frameEnd = peerGroupEnd - partitionStart - 1;\n                break;\n            case PRECEDING:\n                // note: this is the only case where frameEnd might get out of partition bound\n                frameEnd = getFrameEndPreceding(recentRange.getEnd(), frameInfo, endComparator);\n                break;\n            case FOLLOWING:\n                frameEnd = getFrameEndFollowing(recentRange.getEnd(), frameInfo, endComparator);\n                break;\n            default:\n                // end type cannot be UNBOUNDED_PRECEDING\n                throw new IllegalArgumentException(\"Unsupported frame end type: \" + frameInfo.getStartType());\n        }\n\n        return new Range(frameStart, frameEnd);\n    }\n\n    private int getFrameStartPreceding(int recent, FrameInfo frameInfo, PagesIndexComparator comparator)\n    {\n        int sortKeyChannel = frameInfo.getSortKeyChannelForStartComparison();\n        Ordering ordering = frameInfo.getOrdering().get();\n\n        // If the recent frame start points at a null, it means that we are now processing first non-null position.\n        // For frame start \"X PRECEDING\", the frame starts at the first null for all null values, and it never includes nulls for non-null values.\n        if (pagesIndex.isNull(frameInfo.getSortKeyChannel(), partitionStart + recent)) {\n            return currentPosition - partitionStart;\n        }\n\n        return seek(\n                comparator,","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/operator/window/WindowPartition.java#L374-L410","documentation":"Same family as 2375 but for the frame end boundary: the switch on frameInfo.getEndType() only accepts UNBOUNDED_FOLLOWING, PRECEDING, CURRENT_ROW, and FOLLOWING; the default branch throws because UNBOUNDED_PRECEDING is not a valid frame end. Note the message text uses getStartType() — a message-content quirk in this code.","triggerScenarios":"A FrameInfo with endType UNBOUNDED_PRECEDING or unknown end type reaching getFrameRange — only via internal/planner bugs or hand-built FrameInfo.","commonSituations":"Internal bugs where frame analysis permits an invalid end type; custom window-operator construction.","solutions":["Use only valid frame ends in OVER clauses: CURRENT ROW, <n> PRECEDING/FOLLOWING, or UNBOUNDED FOLLOWING.","Validate FrameInfo endType in custom code before execution.","File a bug with the plan if hit on stock build."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"-- valid frame ends only: CURRENT ROW, <n> PRECEDING/FOLLOWING, UNBOUNDED FOLLOWING\nSELECT sum(x) OVER (ORDER BY t ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) FROM tab;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never specify UNBOUNDED PRECEDING as a frame end.","Lint window functions in CI to catch invalid frame specs.","Report reproducible planner inconsistencies as bugs."],"tags":["window-function","internal-error","frame"],"backgroundTag":"unsupported-frame-type","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"}