{"record":{"id":"a32c5a99454bc656","repo":"louthy/language-ext","slug":"unable-to-get-x-y-from-change-matrix","errorCode":null,"errorMessage":"Unable to get ({x},{y}) from change matrix","messagePattern":"Unable to get \\((.+?),(.+?)\\) from change matrix","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"LanguageExt.Core/DataTypes/Patch/Patch.Internal.cs","lineNumber":72,"sourceCode":"        return vector;\n    }\n\n    public static SpanArray<(C, Seq<Option<O>>)> rawChanges<OrdC, V, O, C>(PatchParams<V, O, C> p, SpanArray<V> src, SpanArray<V> dst)\n        where OrdC : Ord<C>\n        where C : Monoid<C>\n    {\n        var lenX = 1 + dst.Count;\n        var lenY = 1 + src.Count;\n        var lenN = lenX * lenY;\n\n        int ix(int x, int y) => x * lenY + y;\n\n        (C, Seq<Option<O>>) get(SpanArray<(C, Seq<Option<O>>)> m, int x, int y)\n        {\n            int i = ix(x, y);\n            return i < m.Count\n                       ? m[i]\n                       : throw new Exception($\"Unable to get ({x},{y}) from change matrix\");\n        }\n\n        int position(Seq<Option<O>> seq) =>\n            seq.Map(oo => oo.Map(p.positionOffset).IfNone(1)).Sum();\n\n        (C, Seq<Option<O>>) ctr(SpanArray<(C, Seq<Option<O>>)> v)\n        {\n            var (quot, rem) = quotRem(v.Count, lenY);\n\n            if (quot == 0 && rem == 0)\n            {\n                return (C.Empty, Seq<Option<O>>());\n            }\n            else if (quot == 0)\n            {\n                var y = rem - 1;\n                var o = p.delete(0, src[y]);\n                var (pc, po) = get(v, 0, y);","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Core/DataTypes/Patch/Patch.Internal.cs#L54-L90","documentation":"Inside `Patch`'s `rawChanges`, `get` indexes into the change matrix (a `SpanArray<(C, Seq<Option<O>>)>`) using a computed flat index `ix(x, y)`. If the computed index falls outside the matrix's bounds, it throws `Exception(\"Unable to get ({x},{y}) from change matrix\")`, meaning the diff walk attempted to address a cell that doesn't exist — the matrix was built too small or the coordinates are wrong for the input lengths.","triggerScenarios":"Running the patch/diff on inputs whose lengths don't match the allocated change matrix, or inputs that lead the Levenshtein-style walk outside the matrix — e.g. very large collections combined with memory pressure or corrupted position calculations.","commonSituations":"Diffing collections after mutating one of them concurrently; passing collections whose size changed between matrix allocation and traversal; bug reports where diffing specific sequences of differing lengths trips the bound.","solutions":["Ensure the collections passed to the Patch/diff API are not mutated during computation (snapshot them first).","Verify you're using matching library-version APIs (Patch internals changed across LanguageExt versions).","Reduce input to a minimal repro and report the coordinate pair to LanguageExt maintainers if it occurs with stable inputs."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// snapshot lengths before diffing and confirm inputs are immutable during the run\nvar a = listA.ToLst(); var b = listB.ToLst();","typeGuard":null,"tryCatchPattern":"try { var patch = Patch.compute(a, b); }\ncatch (Exception ex) when (ex.Message.StartsWith(\"Unable to get (\")) { /* fall back to replace-all patch */ }","preventionTips":["Never mutate collections concurrently with patch computation.","Snapshot inputs (ToLst/ToArray) before diffing.","Keep LanguageExt versions consistent across modules that share patch code."],"tags":["patch","diff","index-out-of-range","csharp"],"backgroundTag":"index-out-of-range","analyzedSha":"2f0e3628242889774d4141960a35671a0280051f","analyzedAt":"2026-09-15T03:31:55.716Z","contentChangedAt":"2026-09-15T03:31:55.716Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}