{"record":{"id":"5c839e2368b8dd3b","repo":"apache/iceberg","slug":"cannot-parse-description-name","errorCode":null,"errorMessage":"Cannot parse ${description}: ${name}","messagePattern":"Cannot parse (.+?): (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java","lineNumber":827,"sourceCode":"      SparkSession spark, String name, CatalogPlugin defaultCatalog) throws ParseException {\n    ParserInterface parser = spark.sessionState().sqlParser();\n    Seq<String> multiPartIdentifier = parser.parseMultipartIdentifier(name).toIndexedSeq();\n    List<String> javaMultiPartIdentifier = JavaConverters.seqAsJavaList(multiPartIdentifier);\n    return catalogAndIdentifier(spark, javaMultiPartIdentifier, defaultCatalog);\n  }\n\n  public static CatalogAndIdentifier catalogAndIdentifier(\n      String description, SparkSession spark, String name) {\n    return catalogAndIdentifier(\n        description, spark, name, spark.sessionState().catalogManager().currentCatalog());\n  }\n\n  public static CatalogAndIdentifier catalogAndIdentifier(\n      String description, SparkSession spark, String name, CatalogPlugin defaultCatalog) {\n    try {\n      return catalogAndIdentifier(spark, name, defaultCatalog);\n    } catch (ParseException e) {\n      throw new IllegalArgumentException(\"Cannot parse \" + description + \": \" + name, e);\n    }\n  }\n\n  public static CatalogAndIdentifier catalogAndIdentifier(\n      SparkSession spark, List<String> nameParts) {\n    return catalogAndIdentifier(\n        spark, nameParts, spark.sessionState().catalogManager().currentCatalog());\n  }\n\n  /**\n   * A modified version of Spark's LookupCatalog.CatalogAndIdentifier.unapply Attempts to find the\n   * catalog and identifier a multipart identifier represents\n   *\n   * @param spark Spark session to use for resolution\n   * @param nameParts Multipart identifier representing a table\n   * @param defaultCatalog Catalog to use if none is specified\n   * @return The CatalogPlugin and Identifier for the table\n   */","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java#L809-L845","documentation":"Spark3Util.catalogAndIdentifier(description, spark, name, defaultCatalog) parses a table/namespace name string using Spark's parser. If the string is not a valid multipart identifier, the underlying ParseException is rethrown as IllegalArgumentException with the supplied description and the offending name.","triggerScenarios":"Calling Spark3Util.catalogAndIdentifier(description, spark, name, defaultCatalog) (or catalog-based callers like SparkSessionCatalog.loadTable) with a name string Spark's parser cannot parse, e.g. containing stray backticks, unbalanced quotes, or '.' placement like '`db`.`tbl' with a dangling backtick.","commonSituations":"Typo in CLI/SQL catalog names (extra dot like 'catalog..table'); shell quoting stripping backticks; users passing fully-qualified URIs or SQL fragments as table names; session catalog delegation with malformed identifiers.","solutions":["Fix the identifier string: valid form is catalog.namespace.table with properly balanced backticks only around parts needing escaping","Escape backticks inside identifiers by doubling them (``)","If the name comes from user input, validate/normalize it before calling catalogAndIdentifier"],"exampleFix":"// before\nSpark3Util.catalogAndIdentifier(\"table identifier\", spark, \"my`catalog.tbl\", defaultCatalog); // bad backtick placement\n// after\nSpark3Util.catalogAndIdentifier(\"table identifier\", spark, \"my_catalog.default.tbl\", defaultCatalog);","handlingStrategy":"validation","validationCode":"if (name == null || name.trim().isEmpty() || name.contains(\"..\") || countUnbalanced(name, '`') != 0) { throw new IllegalArgumentException(\"Malformed identifier: \" + name); }","typeGuard":"boolean looksLikeMultipartIdentifier(String s) { return s != null && !s.startsWith(\".\") && !s.endsWith(\".\") && !s.contains(\"..\"); }","tryCatchPattern":"try { return Spark3Util.catalogAndIdentifier(\"table identifier\", spark, name, defaultCatalog); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(\"Fix the table name, expected [catalog.][namespace.]table: \" + name, e); }","preventionTips":["Validate identifier strings from user input/CLI before parsing","Remember to double backticks to escape them inside identifiers","Prefer building identifiers from List<String> nameParts via catalogAndIdentifier(spark, nameParts) instead of parsing strings"],"tags":["spark","identifier-parsing","illegal-argument"],"backgroundTag":"invalid-identifier-format","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}