# Buggy code
def __setitem__(self, key, value):
    """__setitem__ is overloaded to access the underlying numpy values with
    orthogonal indexing.

    See __getitem__ for more details.
    """
    dims, index_tuple, new_order = self._broadcast_indexes(key)

    if isinstance(value, Variable):
        value = value.set_dims(dims).data

    if new_order:
        value = duck_array_ops.asarray(value)
        if value.ndim > len(dims):
            raise ValueError(
                "shape mismatch: value array of shape %s could not be"
                "broadcast to indexing result with %s dimensions"
                % (value.shape, len(dims))
            )

        value = value[(len(dims) - value.ndim) * (np.newaxis,) + (Ellipsis,)]
        value = np.moveaxis(value, new_order, range(len(new_order)))

    self._indexable_data[index_tuple] = value


# Traceback (AxisError)
In [8]: xarr.variable[l_indices.variable, c_indices.variable] = 2
---------------------------------------------------------------------------
AxisError                                 Traceback (most recent call last)
<ipython-input-8-75558576dcaf> in <module>()
----> 1 xarr.variable[l_indices.variable, c_indices.variable] = 2

~/dev/xarray/xarray/core/variable.py in __setitem__(self, key, value)
653             value = np.moveaxis(value, new_order, range(len(new_order)))
654
--> 655         self._indexable_data[index_tuple] = value
656
657     @property

~/dev/xarray/xarray/core/indexing.py in __setitem__(self, key, value)
660     def __setitem__(self, key, value):
661         array, key = self._indexing_array_and_key(key)
--> 662         array[key] = value
663
664

~/dev/xarray/xarray/core/nputils.py in __setitem__(self, key, value)
132         mixed_positions, vindex_positions = _advanced_indexer_subspaces(key)
133         self._array[key] = np.moveaxis(value, vindex_positions,
--> 134                                        mixed_positions)

~/conda/envs/xarray-dev/lib/python3.5/site-packages/numpy/core/numeric.py in moveaxis(a, source, destination)
1599         transpose = a.transpose
1600
-> 1601     source = normalize_axis_tuple(source, a.ndim, 'source')
1602     destination = normalize_axis_tuple(destination, a.ndim, 'destination')
1603     if len(source) != len(destination):

~/conda/envs/xarray-dev/lib/python3.5/site-packages/numpy/core/numeric.py in normalize_axis_tuple(axis, ndim, argname, allow_duplicate)
1534     except TypeError:
1535         axis = tuple(axis)
-> 1536     axis = tuple(normalize_axis_index(ax, ndim, argname) for ax in axis)
1537     if not allow_duplicate and len(set(axis)) != len(axis):
1538         if argname:

~/conda/envs/xarray-dev/lib/python3.5/site-packages/numpy/core/numeric.py in <genexpr>(.0)
1534     except TypeError:
1535         axis = tuple(axis)
-> 1536     axis = tuple(normalize_axis_index(ax, ndim, argname) for ax in axis)
1537     if not allow_duplicate and len(set(axis)) != len(axis):
1538         if argname:

AxisError: source: axis 0 is out of bounds for array of dimension 0

# Fixed code
def __setitem__(self, key, value):
    """__setitem__ is overloaded to access the underlying numpy values with
    orthogonal indexing.

    See __getitem__ for more details.
    """
    dims, index_tuple, new_order = self._broadcast_indexes(key)

    if not isinstance(value, Variable):
        value = as_compatible_data(value)
        if value.ndim > len(dims):
            raise ValueError(
                "shape mismatch: value array of shape %s could not be"
                "broadcast to indexing result with %s dimensions"
                % (value.shape, len(dims))
            )
        if value.ndim == 0:
            value = Variable((), value)
        else:
            value = Variable(dims[-value.ndim :], value)
    # broadcast to become assignable
    value = value.set_dims(dims).data

    if new_order:
        value = duck_array_ops.asarray(value)
        value = value[(len(dims) - value.ndim) * (np.newaxis,) + (Ellipsis,)]
        value = np.moveaxis(value, new_order, range(len(new_order)))

    self._indexable_data[index_tuple] = value