{"record":{"id":"e8803771c1b9c7d4","repo":"apache/iceberg","slug":"e-message-rethrown-as-parse-error-with-command-co-e88037","errorCode":null,"errorMessage":"e.message (rethrown as parse error with command context)","messagePattern":"e\\.message \\(rethrown as parse error with command context\\)","errorType":"exception","errorClass":"IcebergParseException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSparkSqlExtensionsParser.scala","lineNumber":202,"sourceCode":"      } catch {\n        case _: ParseCancellationException =>\n          // if we fail, parse with LL mode with DefaultErrorStrategy\n          tokenStream.seek(0) // rewind input stream\n          parser.reset()\n\n          // Try Again.\n          parser.setErrorHandler(new DefaultErrorStrategy)\n          parser.getInterpreter.setPredictionMode(PredictionMode.LL)\n          toResult(parser)\n      }\n    } catch {\n      case e: IcebergParseException if e.command.isDefined =>\n        throw e\n      case e: IcebergParseException =>\n        throw e.withCommand(command)\n      case e: AnalysisException =>\n        val position = Origin(e.line, e.startPosition)\n        throw new IcebergParseException(Option(command), e.message, position, position)\n    }\n  }\n\n  override def parseQuery(sqlText: String): LogicalPlan = {\n    parsePlan(sqlText)\n  }\n}\n\nobject IcebergSparkSqlExtensionsParser {\n  private val substitutorCtor: DynConstructors.Ctor[VariableSubstitution] =\n    DynConstructors\n      .builder()\n      .impl(classOf[VariableSubstitution])\n      .impl(classOf[VariableSubstitution], classOf[SQLConf])\n      .build()\n}\n\n/* Copied from Apache Spark's to avoid dependency on Spark Internals */","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSparkSqlExtensionsParser.scala#L184-L220","documentation":"When parsePlan fails, Iceberg rethrows parse errors, attaching the original SQL command text to the exception so the message includes the offending statement. An IcebergParseException that already has a command is rethrown as-is; one without a command gets withCommand(command) applied; an AnalysisException is converted into an IcebergParseException carrying the line/position origins. The surfaced error message is the underlying parse failure plus command context.","triggerScenarios":"Any invalid Iceberg SQL extension syntax (ALTER TABLE ... TBLPROPERTIES, CALL, etc.) submitted through sql() that fails the Iceberg grammar; also AnalysisExceptions raised during parsing are rewrapped as IcebergParseException.","commonSituations":"Typo in Iceberg DDL extensions, using Iceberg-specific syntax on a Spark version whose grammar differs, or copy-pasted SQL from docs of a different Iceberg/Spark version.","solutions":["Fix the SQL syntax per the Iceberg DDL docs for your Spark version","Read the command context in the message to locate the offending statement and position","Verify the Iceberg spark-extensions jar version matches your Spark major version (e.g. spark-extensions for 4.0)"],"exampleFix":"// before\nspark.sql(\"ALTER TABLE t WRITE ORDERED BY badcolumnexpr(\") // parse error\n// after\nspark.sql(\"ALTER TABLE t WRITE ORDERED BY id\")","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { spark.sql(stmt) } catch { case e: IcebergParseException => log.error(s\"Failed to parse: ${e.command.getOrElse(stmt)} at line ${e.line}:${e.startPosition}\", e) }","preventionTips":["Validate Iceberg DDL against docs for your exact Spark/Iceberg version","Enable parse-error logging to capture command context","Test extension SQL in a staging session before production"],"tags":["spark","parser","sql-syntax"],"backgroundTag":"invalid-argument-format","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}