{"record":{"id":"fc35c3d4ef5398f3","repo":"prestodb/presto","slug":"generic-internal-error-fc35c3","errorCode":"GENERIC_INTERNAL_ERROR","errorMessage":"unresolvable order for two inserts","messagePattern":"unresolvable order for two inserts","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-iceberg/src/main/java/com/facebook/presto/iceberg/function/changelog/ChangelogRecord.java","lineNumber":98,"sourceCode":"        return lastOperation;\n    }\n\n    public ChangelogRecord merge(ChangelogRecord other)\n    {\n        if (other.lastOrdinal > lastOrdinal) {\n            this.lastOperation = other.lastOperation;\n            this.lastRow = other.lastRow;\n            this.lastOrdinal = other.lastOrdinal;\n        }\n        else if (other.lastOrdinal == lastOrdinal) {\n            // ordinals are equal. In the case both operations are inserts, we\n            // don't have a way to break ties. Likely an error, throw exception\n            ChangelogOperation operation = ChangelogOperation.valueOf(other.lastOperation.toStringUtf8().toUpperCase());\n            switch (operation) {\n                case UPDATE_AFTER:\n                case INSERT:\n                    if (ChangelogOperation.valueOf(lastOperation.toStringUtf8().toUpperCase()).equals(INSERT)) {\n                        throw new PrestoException(StandardErrorCode.GENERIC_INTERNAL_ERROR, \"unresolvable order for two inserts\");\n                    }\n                    lastOperation = other.lastOperation;\n                    lastRow = other.lastRow;\n                    lastOrdinal = other.lastOrdinal;\n                    break;\n                case UPDATE_BEFORE:\n                case DELETE:\n                    // we don't need to record data before a record update/delete\n                    break;\n                default:\n                    throw new PrestoException(StandardErrorCode.GENERIC_INTERNAL_ERROR, \"unsupported operation type \" + operation);\n            }\n        }\n        return this;\n    }\n\n    public void serialize(BlockBuilder out)\n    {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-iceberg/src/main/java/com/facebook/presto/iceberg/function/changelog/ChangelogRecord.java#L80-L116","documentation":"ChangelogRecord.merge folds two changelog records into one during incremental changelog aggregation. When both records are INSERT operations there is no way to order them or break ties, so the state would be ambiguous. The code treats this as an unrecoverable internal inconsistency and throws GENERIC_INTERNAL_ERROR rather than producing silently wrong results.","triggerScenarios":"Calling ChangelogRecord.add/merge with another record whose lastOperation is INSERT while this record's lastOperation is also INSERT — i.e. combining aggregation state from two separate inserts of the same key.","commonSituations":"Streaming changelog sources that emit duplicate inserts for the same primary key; re-emitted or replayed CDC events during source restarts; running changelog aggregation with incorrectly keyed partitions so two inserts collide in one aggregation group.","solutions":["Deduplicate upstream so only one INSERT per key reaches the aggregation (correct source keying on primary key).","Ensure the changelog stream emits UPDATE_BEFORE/UPDATE_AFTER pairs instead of raw inserts for updates.","If duplicates are expected from replays, enable idempotent/exactly-once consumption or filter replayed ordinals before aggregation.","Report as a bug if it occurs with a well-formed single-writer CDC stream — the engine should never see two inserts for one key."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// upstream: ensure exactly-once and primary-key keying for the CDC stream\n// reject duplicate inserts before aggregation\nif (seenKeys.putIfAbsent(record.key(), record.ordinal()) != null && record.op().equals(\"INSERT\")) {\n    throw new IllegalStateException(\"duplicate insert for key \" + record.key());\n}","typeGuard":null,"tryCatchPattern":"try {\n    state.add(record);\n} catch (PrestoException e) {\n    if (e.getErrorCode().getName().equals(\"GENERIC_INTERNAL_ERROR\")) {\n        // restart aggregation from a clean checkpoint; do not retry into the same state\n        state = new ChangelogRecord(...);\n    }\n}","preventionTips":["Key the changelog stream on the primary key.","Deduplicate replayed events at the source.","Emit proper update_before/update_after pairs instead of bare inserts."],"tags":[],"backgroundTag":null,"analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}