{"record":{"id":"33a7f12b2b913fcd","repo":"DrKLO/Telegram","slug":"unknown-flag-for-pos","errorCode":null,"errorMessage":"unknown flag for pos {} {}","messagePattern":"unknown flag for pos (.+?) (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"TMessagesProj/src/main/java/androidx/recyclerview/widget/DiffUtil.java","lineNumber":904,"sourceCode":"                    case FLAG_MOVED_CHANGED:\n                    case FLAG_MOVED_NOT_CHANGED:\n                        final int pos = mNewItemStatuses[globalIndex + i] >> FLAG_OFFSET;\n                        final PostponedUpdate update = removePostponedUpdate(postponedUpdates, pos,\n                                true);\n                        // the item was moved from that position\n                        //noinspection ConstantConditions\n                        updateCallback.onMoved(update.currentPos, start);\n                        if (status == FLAG_MOVED_CHANGED) {\n                            // also dispatch a change\n                            updateCallback.onChanged(start, 1,\n                                    mCallback.getChangePayload(pos, globalIndex + i));\n                        }\n                        break;\n                    case FLAG_IGNORE: // ignoring this\n                        postponedUpdates.add(new PostponedUpdate(globalIndex + i, start, false));\n                        break;\n                    default:\n                        throw new IllegalStateException(\n                                \"unknown flag for pos \" + (globalIndex + i) + \" \" + Long\n                                        .toBinaryString(status));\n                }\n            }\n        }\n\n        private void dispatchRemovals(List<PostponedUpdate> postponedUpdates,\n                ListUpdateCallback updateCallback, int start, int count, int globalIndex) {\n            if (!mDetectMoves) {\n                updateCallback.onRemoved(start, count);\n                return;\n            }\n            for (int i = count - 1; i >= 0; i--) {\n                final int status = mOldItemStatuses[globalIndex + i] & FLAG_MASK;\n                switch (status) {\n                    case 0: // real removal\n                        updateCallback.onRemoved(start + i, 1);\n                        for (PostponedUpdate update : postponedUpdates) {","sourceCodeStart":886,"sourceCodeEnd":922,"githubUrl":"https://github.com/DrKLO/Telegram/blob/45ab8f4308496e1f01026a97fcdb0d58a5274474/TMessagesProj/src/main/java/androidx/recyclerview/widget/DiffUtil.java#L886-L922","documentation":"While dispatching ADDITIONS during DiffResult.dispatchUpdatesTo, each position has a status flag encoding its fate (added, moved, moved-and-changed, ignored). The switch covers the known FLAG_* constants; the default fires when the status word has an unrecognized combination — which should never happen for a correctly computed DiffResult. Reaching it means the internal mOldItemStatuses/mNewItemStatuses arrays were populated incorrectly, almost always because the DiffUtil.Callback returned inconsistent results (the same root cause as error 8: data changed during the diff).","triggerScenarios":"DiffUtil.Callback.areItemsTheSame/areContentsTheSame return contradictory answers across calls (e.g. item hashes differ run to run); the source list mutated during calculateDiff; getChangePayload returns inconsistent data causing flag mis-encoding; a custom Callback that returns true for areItemsTheSame but true for areContentsTheSame inconsistently across the same pair.","commonSituations":"Items whose hashCode/equality changes between calls (mutable fields mutated mid-diff); DB-backed list where the query result set shifted during the diff; using getOldListSize/getNewListSize that read live collections.","solutions":["Snapshot both lists before computing the diff so areItemsTheSame sees stable data.","Ensure areItemsTheSame and areContentsTheSame are deterministic and consistent for the same (oldItem,newItem) pair.","Make item identity (areItemsTheSame) stable via a unique id, not mutable fields.","Avoid getChangePayload side effects that touch the source list."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Deterministic Callback over snapshots\nList<Item> oldSnap, newSnap; // frozen\nnew DiffUtil.Callback() {\n    public boolean areItemsTheSame(int o, int n) {\n        return oldSnap.get(o).id == newSnap.get(n).id; // stable id\n    }\n    public boolean areContentsTheSame(int o, int n) {\n        return Objects.equals(oldSnap.get(o), newSnap.get(n));\n    }\n};","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Base areItemsTheSame on a stable unique id, never mutable fields.","Snapshot both lists so Callback answers are consistent across calls.","Keep getChangePayload pure and side-effect free."],"tags":["recyclerview","diffutil","callback","consistency","data-mutation"],"backgroundTag":null,"analyzedSha":"45ab8f4308496e1f01026a97fcdb0d58a5274474","analyzedAt":"2026-08-14T05:19:30.815Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}