{"record":{"id":"d9eae2648fd2e000","repo":"apache/iceberg","slug":"cannot-write-delete-files-in-a-v1-table","errorCode":null,"errorMessage":"Cannot write delete files in a v1 table","messagePattern":"Cannot write delete files in a v1 table","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/ManifestFiles.java","lineNumber":379,"sourceCode":"  /**\n   * Create a new {@link ManifestWriter} for the given format version with custom writer properties.\n   *\n   * @param formatVersion a target format version\n   * @param spec a {@link PartitionSpec}\n   * @param outputFile an {@link EncryptedOutputFile} where the manifest will be written\n   * @param snapshotId a snapshot ID for the manifest entries, or null for an inherited ID\n   * @param writerProperties properties passed through to the underlying file writer\n   * @return a manifest writer\n   */\n  public static ManifestWriter<DeleteFile> writeDeleteManifest(\n      int formatVersion,\n      PartitionSpec spec,\n      EncryptedOutputFile outputFile,\n      Long snapshotId,\n      Map<String, String> writerProperties) {\n    switch (formatVersion) {\n      case 1:\n        throw new IllegalArgumentException(\"Cannot write delete files in a v1 table\");\n      case 2:\n        return new ManifestWriter.V2DeleteWriter(spec, outputFile, snapshotId, writerProperties);\n      case 3:\n        return new ManifestWriter.V3DeleteWriter(spec, outputFile, snapshotId, writerProperties);\n      case 4:\n        return new ManifestWriter.V4DeleteWriter(spec, outputFile, snapshotId, writerProperties);\n    }\n    throw new UnsupportedOperationException(\n        \"Cannot write manifest for table version: \" + formatVersion);\n  }\n\n  /**\n   * Encode the {@link ManifestFile} to a byte array by using avro encoder.\n   *\n   * @param manifestFile a {@link ManifestFile}, which should always be a {@link\n   *     GenericManifestFile}.\n   * @return the binary data.\n   * @throws IOException if encounter any IO error when encoding.","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/ManifestFiles.java#L361-L397","documentation":"Delete files (position/equality deletes) require format version 2 or later; writeDeleteManifest explicitly throws IllegalArgumentException when asked to write a delete manifest for a v1 table since v1 has no delete-file support.","triggerScenarios":"Calling ManifestFiles.writeDeleteManifest with formatVersion 1, or performing a delete/copy-on-write operation against a table whose format-version is 1.","commonSituations":"Trying row-level deletes or MERGE operations on legacy v1 tables; migrating writers but not the table format; misconfigured table creation defaulting to v1.","solutions":["Migrate the table to format version 2 (rewrite table metadata with format-version=2) before writing delete files","Use overwrite/rewrite-based delete semantics for v1 tables instead of delete files","Verify the table's format-version property before running delete jobs"],"exampleFix":"// before: writing delete manifest against a v1 table\nManifestFiles.writeDeleteManifest(1, spec, outputFile, snapshotId, props);\n// after: migrate table to v2 first, then\nManifestFiles.writeDeleteManifest(2, spec, outputFile, snapshotId, props);","handlingStrategy":"validation","validationCode":"if (table.ops().current().formatVersion() < 2) {\n  throw new IllegalStateException(\"Delete files require format version >= 2; migrate the table first\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  ManifestFiles.writeDeleteManifest(formatVersion, spec, out, snapshotId, props);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"v1 table\")) { /* switch to overwrite semantics or migrate */ }\n  else throw e;\n}","preventionTips":["Migrate legacy v1 tables to v2 before enabling row-level deletes","Check format-version before running MERGE/DELETE jobs","Use overwrite-based deletes for v1 tables"],"tags":["java","format-version","delete-files"],"backgroundTag":"invalid-argument-value","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"}