{"record":{"id":"6472ff58f9f883fa","repo":"apache/seatunnel","slug":"non-primary-key-check-error","errorCode":"NON_PRIMARY_KEY_CHECK_ERROR","errorMessage":" `%s` will is empty when `%s`is true, but is %s","messagePattern":" `(.+?)` will is empty when `(.+?)`is true, but is (.+?)","errorType":"error_code","errorClass":"PaimonConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-paimon/src/main/java/org/apache/seatunnel/connectors/seatunnel/paimon/config/PaimonSinkConfig.java","lineNumber":71,"sourceCode":"     * SaveMode auto-create options from {@code table_options}. Applied only when building the\n     * Paimon schema for table creation; not merged into runtime {@link #writeProps}.\n     */\n    private final Map<String, String> tableOptions;\n\n    public PaimonSinkConfig(ReadonlyConfig readonlyConfig) {\n        super(readonlyConfig);\n        this.schemaSaveMode = readonlyConfig.get(PaimonSinkOptions.SCHEMA_SAVE_MODE);\n        this.dataSaveMode = readonlyConfig.get(PaimonSinkOptions.DATA_SAVE_MODE);\n        this.nonPrimaryKey = readonlyConfig.get(PaimonSinkOptions.NON_PRIMARY_KEY);\n        this.primaryKeys = stringToList(readonlyConfig.get(PaimonSinkOptions.PRIMARY_KEYS), \",\");\n        if (this.nonPrimaryKey && !this.primaryKeys.isEmpty()) {\n            String message =\n                    String.format(\n                            \" `%s` will is empty when `%s`is true, but is %s\",\n                            PaimonSinkOptions.PRIMARY_KEYS.key(),\n                            PaimonSinkOptions.NON_PRIMARY_KEY.key(),\n                            this.primaryKeys);\n            throw new PaimonConnectorException(\n                    PaimonConnectorErrorCode.NON_PRIMARY_KEY_CHECK_ERROR, message);\n        }\n        this.partitionKeys =\n                stringToList(readonlyConfig.get(PaimonSinkOptions.PARTITION_KEYS), \",\");\n        this.tableOptions =\n                new HashMap<>(\n                        readonlyConfig\n                                .getOptional(SinkConnectorCommonOptions.TABLE_OPTIONS)\n                                .orElse(Collections.emptyMap()));\n        // Keep write-props as the runtime writer config only; do not merge table_options here.\n        this.writeProps = new HashMap<>(readonlyConfig.get(PaimonSinkOptions.WRITE_PROPS));\n        this.changelogProducer =\n                Stream.of(CoreOptions.ChangelogProducer.values())\n                        .filter(\n                                cp ->\n                                        cp.toString()\n                                                .equalsIgnoreCase(\n                                                        writeProps.getOrDefault(","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-paimon/src/main/java/org/apache/seatunnel/connectors/seatunnel/paimon/config/PaimonSinkConfig.java#L53-L89","documentation":"PaimonSinkConfig validates the sink's primary key configuration. When the `non_primary_key` option is set to true, the `primary_keys` option must be left empty; if primary keys are still configured, the connector throws NON_PRIMARY_KEY_CHECK_ERROR because the two options are contradictory.","triggerScenarios":"Constructing PaimonSinkConfig where readonlyConfig has non_primary_key=true AND a non-empty primary_keys list (e.g. leftover primary_keys from a copied HOCON config).","commonSituations":"Users switch a table to append/non-pk mode by setting non_primary_key=true but forget to delete the primary_keys line; template configs that predefine primary_keys; automated config generation that always emits primary_keys.","solutions":["Remove the `primary_keys` entry from the sink config when `non_primary_key = true`","Or set `non_primary_key = false` if the table really should be a primary-key table","Check the generated/template config for a hardcoded primary_keys default"],"exampleFix":"// before\nnon_primary_key = true\nprimary_keys = [\"id\"]\n// after\nnon_primary_key = true\n","handlingStrategy":"validation","validationCode":"if (config.get(PaimonSinkOptions.NON_PRIMARY_KEY) && !config.get(PaimonSinkOptions.PRIMARY_KEYS).isEmpty()) { throw new IllegalArgumentException(\"primary_keys must be empty when non_primary_key = true\"); }","typeGuard":null,"tryCatchPattern":"try { new PaimonSinkConfig(readonlyConfig); } catch (PaimonConnectorException e) { if (PaimonConnectorErrorCode.NON_PRIMARY_KEY_CHECK_ERROR.equals(e.getErrorCode())) { /* strip primary_keys and rebuild */ } else { throw e; } }","preventionTips":["Never combine non_primary_key=true with primary_keys","Grep generated configs for primary_keys defaults","Add a config lint step before job submission"],"tags":["paimon","config","validation"],"backgroundTag":"conflicting-config-options","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"}