louthy/language-ext · error · Exception

Unable to get ( , ) from change matrix

Error message

Unable to get ({x},{y}) from change matrix

What it means

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.

Solutions

  1. Ensure the collections passed to the Patch/diff API are not mutated during computation (snapshot them first).
  2. Verify you're using matching library-version APIs (Patch internals changed across LanguageExt versions).
  3. Reduce input to a minimal repro and report the coordinate pair to LanguageExt maintainers if it occurs with stable inputs.
Defensive patterns

Strategy: try-catch

Validate before calling

// snapshot lengths before diffing and confirm inputs are immutable during the run
var a = listA.ToLst(); var b = listB.ToLst();

Try / catch

try { var patch = Patch.compute(a, b); }
catch (Exception ex) when (ex.Message.StartsWith("Unable to get (")) { /* fall back to replace-all patch */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15). Data as JSON: /api/errors/a32c5a99454bc656. Report an issue: GitHub.

Appendix: source

Thrown at LanguageExt.Core/DataTypes/Patch/Patch.Internal.cs:72

        return vector;
    }

    public static SpanArray<(C, Seq<Option<O>>)> rawChanges<OrdC, V, O, C>(PatchParams<V, O, C> p, SpanArray<V> src, SpanArray<V> dst)
        where OrdC : Ord<C>
        where C : Monoid<C>
    {
        var lenX = 1 + dst.Count;
        var lenY = 1 + src.Count;
        var lenN = lenX * lenY;

        int ix(int x, int y) => x * lenY + y;

        (C, Seq<Option<O>>) get(SpanArray<(C, Seq<Option<O>>)> m, int x, int y)
        {
            int i = ix(x, y);
            return i < m.Count
                       ? m[i]
                       : throw new Exception($"Unable to get ({x},{y}) from change matrix");
        }

        int position(Seq<Option<O>> seq) =>
            seq.Map(oo => oo.Map(p.positionOffset).IfNone(1)).Sum();

        (C, Seq<Option<O>>) ctr(SpanArray<(C, Seq<Option<O>>)> v)
        {
            var (quot, rem) = quotRem(v.Count, lenY);

            if (quot == 0 && rem == 0)
            {
                return (C.Empty, Seq<Option<O>>());
            }
            else if (quot == 0)
            {
                var y = rem - 1;
                var o = p.delete(0, src[y]);
                var (pc, po) = get(v, 0, y);

View on GitHub (pinned to 2f0e362824)