# Buggy code
def _sort_levels_monotonic(self):
    """
    .. versionadded:: 0.20.0

    This is an *internal* function.

    create a new MultiIndex from the current to monotonically sorted
    items IN the levels. This does not actually make the entire MultiIndex
    monotonic, JUST the levels.

    The resulting MultiIndex will have the same outward
    appearance, meaning the same .values and ordering. It will also
    be .equals() to the original.

    Returns
    -------
    MultiIndex

    Examples
    --------

    >>> i = pd.MultiIndex(levels=[['a', 'b'], ['bb', 'aa']],
                          labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
    >>> i
    MultiIndex(levels=[['a', 'b'], ['bb', 'aa']],
               labels=[[0, 0, 1, 1], [0, 1, 0, 1]])

    >>> i.sort_monotonic()
    MultiIndex(levels=[['a', 'b'], ['aa', 'bb']],
               labels=[[0, 0, 1, 1], [1, 0, 1, 0]])

    """

    if self.is_lexsorted() and self.is_monotonic:
        return self

    new_levels = []
    new_labels = []

    for lev, lab in zip(self.levels, self.labels):
        if lev.is_monotonic:
            new_levels.append(lev)
            new_labels.append(lab)
            continue

        # indexer to reorder the levels
        indexer = lev.argsort()
        lev = lev.take(indexer)

        # indexer to reorder the labels
        indexer = _ensure_int64(indexer)
        ri = lib.get_reverse_indexer(indexer, len(indexer))
        lab = algos.take_1d(ri, lab)

        new_levels.append(lev)
        new_labels.append(lab)

    return MultiIndex(
        new_levels,
        new_labels,
        names=self.names,
        sortorder=self.sortorder,
        verify_integrity=False,
    )


# Traceback (TypeError)
In [2]: df = pd.DataFrame(1, index=range(3), columns=pd.MultiIndex.from_product([['a', 'b'], [1, 2]]))

In [3]: df['c'] = 2

In [4]: df.stack(0)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-a437419299b6> in <module>()
----> 1 df.stack(0)

/home/nobackup/repo/pandas/pandas/core/frame.py in stack(self, level, dropna)
4500             return stack_multiple(self, level, dropna=dropna)
4501         else:
-> 4502             return stack(self, level, dropna=dropna)
4503
4504     def unstack(self, level=-1, fill_value=None):

/home/nobackup/repo/pandas/pandas/core/reshape/reshape.py in stack(frame, level, dropna)
513
514     if isinstance(frame.columns, MultiIndex):
--> 515         return _stack_multi_columns(frame, level_num=level_num, dropna=dropna)
516     elif isinstance(frame.index, MultiIndex):
517         new_levels = list(frame.index.levels)

/home/nobackup/repo/pandas/pandas/core/reshape/reshape.py in _stack_multi_columns(frame, level_num, dropna)
619         # level
620         level_to_sort = _convert_level_number(0, this.columns)
--> 621         this = this.sort_index(level=level_to_sort, axis=1)
622
623     # tuple list excluding level for grouping columns

/home/nobackup/repo/pandas/pandas/core/frame.py in sort_index(self, axis, level, ascending, inplace, kind, na_position, sort_remaining, by)
3673             # make sure that the axis is lexsorted to start
3674             # if not we need to reconstruct to get the correct indexer
-> 3675             labels = labels._sort_levels_monotonic()
3676             indexer = lexsort_indexer(labels._get_labels_for_sorting(),
3677                                       orders=ascending,

/home/nobackup/repo/pandas/pandas/core/indexes/multi.py in _sort_levels_monotonic(self)
1275
1276             # indexer to reorder the levels
-> 1277             indexer = lev.argsort()
1278             lev = lev.take(indexer)
1279

/home/nobackup/repo/pandas/pandas/core/indexes/base.py in argsort(self, *args, **kwargs)
2146         if result is None:
2147             result = np.array(self)
-> 2148         return result.argsort(*args, **kwargs)
2149
2150     def __add__(self, other):

TypeError: unorderable types: str() > int()

# Fixed code
def _sort_levels_monotonic(self):
    """
    .. versionadded:: 0.20.0

    This is an *internal* function.

    create a new MultiIndex from the current to monotonically sorted
    items IN the levels. This does not actually make the entire MultiIndex
    monotonic, JUST the levels.

    The resulting MultiIndex will have the same outward
    appearance, meaning the same .values and ordering. It will also
    be .equals() to the original.

    Returns
    -------
    MultiIndex

    Examples
    --------

    >>> i = pd.MultiIndex(levels=[['a', 'b'], ['bb', 'aa']],
                          labels=[[0, 0, 1, 1], [0, 1, 0, 1]])
    >>> i
    MultiIndex(levels=[['a', 'b'], ['bb', 'aa']],
               labels=[[0, 0, 1, 1], [0, 1, 0, 1]])

    >>> i.sort_monotonic()
    MultiIndex(levels=[['a', 'b'], ['aa', 'bb']],
               labels=[[0, 0, 1, 1], [1, 0, 1, 0]])

    """

    if self.is_lexsorted() and self.is_monotonic:
        return self

    new_levels = []
    new_labels = []

    for lev, lab in zip(self.levels, self.labels):
        if not lev.is_monotonic:
            try:
                # indexer to reorder the levels
                indexer = lev.argsort()
            except TypeError:
                pass
            else:
                lev = lev.take(indexer)

                # indexer to reorder the labels
                indexer = _ensure_int64(indexer)
                ri = lib.get_reverse_indexer(indexer, len(indexer))
                lab = algos.take_1d(ri, lab)

        new_levels.append(lev)
        new_labels.append(lab)

    return MultiIndex(
        new_levels,
        new_labels,
        names=self.names,
        sortorder=self.sortorder,
        verify_integrity=False,
    )