{"record":{"id":"f50a8441703416c6","repo":"apache/seatunnel","slug":"unsupported-branch-save-mode","errorCode":"UNSUPPORTED_BRANCH_SAVE_MODE","errorMessage":"Paimon branch '${branch}' does not support this save mode for table '${tablePath}'. The main table must exist before writing to a non-main branch.","messagePattern":"Paimon branch '(.+?)' does not support this save mode for table '(.+?)'\\. The main table must exist before writing to a non-main branch\\.","errorType":"error_code","errorClass":"PaimonConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-paimon/src/main/java/org/apache/seatunnel/connectors/seatunnel/paimon/handler/PaimonSaveModeHandler.java","lineNumber":96,"sourceCode":"    }\n\n    @Override\n    public void handleSchemaSaveModeWithRestore() {\n        checkBranchSaveMode();\n        super.handleSchemaSaveModeWithRestore();\n    }\n\n    private boolean isNonMainBranch() {\n        return StringUtils.isNotEmpty(branch)\n                && !BranchManager.DEFAULT_MAIN_BRANCH.equalsIgnoreCase(branch);\n    }\n\n    private void checkBranchSaveMode() {\n        if (!isNonMainBranch()) {\n            return;\n        }\n        if (!catalog.tableExists(tablePath)) {\n            throw unsupportedBranchSaveMode(\n                    \"The main table must exist before writing to a non-main branch.\");\n        }\n        Table paimonTable = ((PaimonCatalog) catalog).getPaimonTable(tablePath);\n        if (!((FileStoreTable) paimonTable).branchManager().branchExists(branch)) {\n            throw new PaimonConnectorException(\n                    PaimonConnectorErrorCode.BRANCH_NOT_EXISTS,\n                    String.format(\n                            \"Specified branch '%s' of table '%s' does not exist.\",\n                            branch, tablePath));\n        }\n        if (this.schemaSaveMode == SchemaSaveMode.RECREATE_SCHEMA) {\n            throw unsupportedBranchSaveMode(\n                    \"schema_save_mode=RECREATE_SCHEMA would drop and recreate the main table.\");\n        }\n        if (this.dataSaveMode == DataSaveMode.DROP_DATA) {\n            throw unsupportedBranchSaveMode(\n                    \"data_save_mode=DROP_DATA would truncate the main table.\");\n        }","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-paimon/src/main/java/org/apache/seatunnel/connectors/seatunnel/paimon/handler/PaimonSaveModeHandler.java#L78-L114","documentation":"When writing to a non-main Paimon branch, the main table must already exist; branch writes operate on an existing table's branch, not a fresh one. If the main table is absent, save-mode handling cannot proceed safely and throws UNSUPPORTED_BRANCH_SAVE_MODE.","triggerScenarios":"sink with branch configured to a non-main branch while schema_save_mode/data_save_mode handling runs and catalog.tableExists(tablePath) is false — i.e. first-time write where the main table was never created.","commonSituations":"Creating the table implicitly via a sink write to a branch; dropped main table but branch config still set; typo in table path so existence check fails.","solutions":["Create the main table first (e.g. via catalog/CREATE TABLE or a prior job writing to the main branch), then write to the branch","Remove the branch option or set it to 'main' for the initial table creation run","Verify the table path spelling matches an existing table"],"exampleFix":"// before: first run directly on a branch\nsink { Paimon { branch = \"audit\", schema_save_mode = CREATE_SCHEMA_WHEN_NOT_EXIST } }\n// after: create main table first, then branch write\nsink { Paimon { schema_save_mode = CREATE_SCHEMA_WHEN_NOT_EXIST } } // run once on main\nsink { Paimon { branch = \"audit\" } } // then write to branch","handlingStrategy":"validation","validationCode":"// before running a branch write, ensure the main table exists\n// via Paimon catalog:\nif (!catalog.tableExists(TablePath.of(\"db.db.tbl\"))) {\n    catalog.createTable(TablePath.of(\"db.db.tbl\"), schema, partitions, props);\n}","typeGuard":null,"tryCatchPattern":"try {\n    handleSaveMode();\n} catch (PaimonConnectorException e) {\n    if (e.getErrorCode() == UNSUPPORTED_BRANCH_SAVE_MODE && e.getMessage().contains(\"must exist\")) {\n        createMainTableThenRetry();\n    } else throw e;\n}","preventionTips":["Always create the main table before configuring branch writes","Verify table paths against the catalog before job submission","Avoid implicit table creation when using branches"],"tags":["paimon","branch","save-mode","sink"],"backgroundTag":"unsupported-operation","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}