Unity-Technologies/UnityCsReference · error · ArgumentException

SwapColumn is only supported for columns next to each other

Error message

SwapColumn is only supported for columns next to each other otherwise visible columns and sorted columns will be incorrect. Column index {columnIndex}, targetColumnIndex {targetColumnIndex}

What it means

Thrown by MultiColumnHeaderState.SwapColumns when columnIndex and targetColumnIndex are not adjacent (absolute difference != 1). The swap logic only updates visible/sorted column mappings correctly for neighboring columns, so non-adjacent swaps are forbidden to avoid corrupting state.

Source

Thrown at Editor/Mono/GUI/TreeView/MultiColumnHeaderState.cs:115

                if (value != current)
                {
                    if (value >= 0)
                    {
                        m_SortedColumns.Remove(value);
                        m_SortedColumns.Insert(0, value);
                    }
                    else
                    {
                        m_SortedColumns.Clear();
                    }
                }
            }
        }

        internal void SwapColumns(int columnIndex, int targetColumnIndex)
        {
            if (Mathf.Abs(columnIndex - targetColumnIndex) != 1)
                throw new ArgumentException("SwapColumn is only supported for columns next to each other otherwise visible columns and sorted columns will be incorrect. Column index " + columnIndex + ", targetColumnIndex " + targetColumnIndex);

            // Swap columns
            var temp = columns[columnIndex];
            columns[columnIndex] = columns[targetColumnIndex];
            columns[targetColumnIndex] = temp;

            // Swap visible columns state so it matches swapped columns above
            for (int i = 0; i < m_VisibleColumns.Length; i++)
            {
                if (m_VisibleColumns[i] == columnIndex)
                    m_VisibleColumns[i] = targetColumnIndex;
                else if (m_VisibleColumns[i] == targetColumnIndex)
                    m_VisibleColumns[i] = columnIndex;
            }
            var list = new List<int>(m_VisibleColumns);
            list.Sort();
            m_VisibleColumns = list.ToArray();

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Implement arbitrary reorder as a sequence of single-step (adjacent) swaps between source and target.
  2. Validate Mathf.Abs(columnIndex - targetColumnIndex) == 1 before calling.
  3. If you need full reordering, rebuild the columns/visibleColumns arrays directly instead of using SwapColumns.

Example fix

// before
state.SwapColumns(from, to); // |from-to| > 1 throws

// after
int step = from < to ? 1 : -1;
for (int i = from; i != to; i += step)
    state.SwapColumns(i, i + step);
Defensive patterns

Strategy: validation

Validate before calling

if (Mathf.Abs(columnIndex - targetColumnIndex) != 1) throw new InvalidOperationException("non-adjacent swap");

Type guard

static bool AreAdjacent(int a, int b) => Mathf.Abs(a - b) == 1;

Prevention

When it happens

Trigger: Calling SwapColumns with indices differing by more than 1 (e.g. swapping column 0 with column 3).

Common situations: Drag-reorder UI allowing multi-step moves; a script attempting arbitrary column reordering via repeated SwapColumns.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/38517f397b46fc94. Report an issue: GitHub.