{"record":{"id":"18e9c667edd0d852","repo":"prestodb/presto","slug":"unsupported-explain-format","errorCode":null,"errorMessage":"Unsupported EXPLAIN format: ","messagePattern":"Unsupported EXPLAIN format: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java","lineNumber":1335,"sourceCode":"    @Override\n    public Node visitExplain(SqlBaseParser.ExplainContext context)\n    {\n        return new Explain(getLocation(context), context.ANALYZE() != null, context.VERBOSE() != null, (Statement) visit(context.statement()), visit(context.explainOption(), ExplainOption.class));\n    }\n\n    @Override\n    public Node visitExplainFormat(SqlBaseParser.ExplainFormatContext context)\n    {\n        switch (context.value.getType()) {\n            case SqlBaseLexer.GRAPHVIZ:\n                return new ExplainFormat(getLocation(context), ExplainFormat.Type.GRAPHVIZ);\n            case SqlBaseLexer.TEXT:\n                return new ExplainFormat(getLocation(context), ExplainFormat.Type.TEXT);\n            case SqlBaseLexer.JSON:\n                return new ExplainFormat(getLocation(context), ExplainFormat.Type.JSON);\n        }\n\n        throw new IllegalArgumentException(\"Unsupported EXPLAIN format: \" + context.value.getText());\n    }\n\n    @Override\n    public Node visitExplainType(SqlBaseParser.ExplainTypeContext context)\n    {\n        switch (context.value.getType()) {\n            case SqlBaseLexer.LOGICAL:\n                return new ExplainType(getLocation(context), ExplainType.Type.LOGICAL);\n            case SqlBaseLexer.DISTRIBUTED:\n                return new ExplainType(getLocation(context), ExplainType.Type.DISTRIBUTED);\n            case SqlBaseLexer.VALIDATE:\n                return new ExplainType(getLocation(context), ExplainType.Type.VALIDATE);\n            case SqlBaseLexer.IO:\n                return new ExplainType(getLocation(context), ExplainType.Type.IO);\n        }\n\n        throw new IllegalArgumentException(\"Unsupported EXPLAIN type: \" + context.value.getText());\n    }","sourceCodeStart":1317,"sourceCodeEnd":1353,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java#L1317-L1353","documentation":"AstBuilder.visitExplainFormat throws this IllegalArgumentException when the grammar reduced an EXPLAIN FORMAT clause whose token does not map to a known ExplainFormat.Type (only TEXT and JSON are handled). It is a parser-side sanity check that should be unreachable for valid grammar input, so hitting it means the grammar and the enum are out of sync or the ANTLR-generated classes were regenerated inconsistently.","triggerScenarios":"Executing 'EXPLAIN ANALYZE? ... FORMAT <x>' where the FORMAT token is neither TEXT nor JSON (e.g. FORMAT GRAPHVIZ removed from the grammar's switch), or running a stale/incompatible presto-parser build where SqlBase.g4 accepts more format tokens than AstBuilder handles.","commonSituations":"Copy-pasted EXPLAIN statements from other engines (e.g. FORMAT YAML), custom forks that added a lexer token without extending visitExplainFormat, or version-mismatched shaded parser jars.","solutions":["Use FORMAT TEXT or FORMAT JSON, which are the only supported values.","Remove the FORMAT clause entirely to get the default text output.","If you maintain a fork, add the new token's case in visitExplainFormat and a matching ExplainFormat.Type.","Rebuild/align presto-parser so the generated SqlBaseParser/Lexer matches AstBuilder."],"exampleFix":"// before\nEXPLAIN FORMAT GRAPHVIZ SELECT * FROM t;\n// after\nEXPLAIN FORMAT TEXT SELECT * FROM t;","handlingStrategy":"validation","validationCode":"Set<String> allowed = Set.of(\"TEXT\", \"JSON\");\nif (format != null && !allowed.contains(format.toUpperCase(Locale.ROOT))) {\n    throw new IllegalArgumentException(\"EXPLAIN FORMAT must be TEXT or JSON: \" + format);\n}","typeGuard":"boolean isSupportedExplainFormat(String s) {\n    return s != null && (s.equalsIgnoreCase(\"TEXT\") || s.equalsIgnoreCase(\"JSON\"));\n}","tryCatchPattern":"try {\n    parser.createStatement(sql);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Unsupported EXPLAIN format\")) {\n        sql = sql.replaceFirst(\"(?i)FORMAT\\\\s+\\\\S+\", \"FORMAT TEXT\");\n        parser.createStatement(sql);\n    } else throw e;\n}","preventionTips":["Only emit FORMAT TEXT or FORMAT JSON in query tooling.","Keep the grammar and AstBuilder in sync when adding formats.","Pin a single version of the shaded presto-parser artifact."],"tags":["sql-parser","explain","illegal-argument"],"backgroundTag":"unsupported-enum-value","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"}