# Buggy code
def _groupby_and_merge(by, on, left: "DataFrame", right: "DataFrame", merge_pieces):
    """
    groupby & merge; we are always performing a left-by type operation

    Parameters
    ----------
    by: field to group
    on: duplicates field
    left: DataFrame
    right: DataFrame
    merge_pieces: function for merging
    """
    pieces = []
    if not isinstance(by, (list, tuple)):
        by = [by]

    lby = left.groupby(by, sort=False)
    rby: Optional[groupby.DataFrameGroupBy] = None

    # if we can groupby the rhs
    # then we can get vastly better perf

    try:
        rby = right.groupby(by, sort=False)
    except KeyError:
        pass

    for key, lhs in lby:
        if rby is None:
            rhs = right
        else:
            try:
                rhs = right.take(rby.indices[key])
            except KeyError:
                # key doesn't exist in left
                lcols = lhs.columns.tolist()
                cols = lcols + [r for r in right.columns if r not in set(lcols)]
                merged = lhs.reindex(columns=cols)
                merged.index = range(len(merged))
                pieces.append(merged)
                continue

        merged = merge_pieces(lhs, rhs)

        # make sure join keys are in the merged
        # TODO, should merge_pieces do this?
        for k in by:
            if k in merged:
                merged[k] = key

        pieces.append(merged)

    # preserve the original order
    # if we have a missing piece this can be reset
    from pandas.core.reshape.concat import concat

    result = concat(pieces, ignore_index=True)
    result = result.reindex(columns=pieces[0].columns, copy=False)
    return result, lby


# Traceback (ValueError)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/site-packages/pandas/core/reshape/merge.py", line 290, in merge_ordered
result, _ = _groupby_and_merge(
File "/usr/lib/python3.8/site-packages/pandas/core/reshape/merge.py", line 162, in _groupby_and_merge
merged[k] = key
File "/usr/lib/python3.8/site-packages/pandas/core/frame.py", line 2938, in __setitem__
self._set_item(key, value)
File "/usr/lib/python3.8/site-packages/pandas/core/frame.py", line 3000, in _set_item
value = self._sanitize_column(key, value)
File "/usr/lib/python3.8/site-packages/pandas/core/frame.py", line 3636, in _sanitize_column
value = sanitize_index(value, self.index, copy=False)
File "/usr/lib/python3.8/site-packages/pandas/core/internals/construction.py", line 611, in sanitize_index
raise ValueError("Length of values does not match length of index")
ValueError: Length of values does not match length of index

# Fixed code
def _groupby_and_merge(by, on, left: "DataFrame", right: "DataFrame", merge_pieces):
    """
    groupby & merge; we are always performing a left-by type operation

    Parameters
    ----------
    by: field to group
    on: duplicates field
    left: DataFrame
    right: DataFrame
    merge_pieces: function for merging
    """
    pieces = []
    if not isinstance(by, (list, tuple)):
        by = [by]

    lby = left.groupby(by, sort=False)
    rby: Optional[groupby.DataFrameGroupBy] = None

    # if we can groupby the rhs
    # then we can get vastly better perf

    try:
        rby = right.groupby(by, sort=False)
    except KeyError:
        pass

    for key, lhs in lby:
        if rby is None:
            rhs = right
        else:
            try:
                rhs = right.take(rby.indices[key])
            except KeyError:
                # key doesn't exist in left
                lcols = lhs.columns.tolist()
                cols = lcols + [r for r in right.columns if r not in set(lcols)]
                merged = lhs.reindex(columns=cols)
                merged.index = range(len(merged))
                pieces.append(merged)
                continue

        merged = merge_pieces(lhs, rhs)

        # make sure join keys are in the merged
        # TODO, should merge_pieces do this?
        merged[by] = key

        pieces.append(merged)

    # preserve the original order
    # if we have a missing piece this can be reset
    from pandas.core.reshape.concat import concat

    result = concat(pieces, ignore_index=True)
    result = result.reindex(columns=pieces[0].columns, copy=False)
    return result, lby