# Buggy code
def _wrap_applied_output(self, keys, values, not_indexed_same=False):
    if len(keys) == 0:
        return self.obj._constructor(index=keys)

    # GH12824
    first_not_none = next(com.not_none(*values), None)

    if first_not_none is None:
        # GH9684 - All values are None, return an empty frame.
        return self.obj._constructor()
    elif isinstance(first_not_none, DataFrame):
        return self._concat_objects(keys, values, not_indexed_same=not_indexed_same)

    key_index = self.grouper.result_index if self.as_index else None

    if isinstance(first_not_none, (np.ndarray, Index)):
        # GH#1738: values is list of arrays of unequal lengths
        #  fall through to the outer else clause
        # TODO: sure this is right?  we used to do this
        #  after raising AttributeError above
        return self.obj._constructor_sliced(
            values, index=key_index, name=self._selection_name
        )
    elif not isinstance(first_not_none, Series):
        # values are not series or array-like but scalars
        # self._selection_name not passed through to Series as the
        # result should not take the name of original selection
        # of columns
        if self.as_index:
            return self.obj._constructor_sliced(values, index=key_index)
        else:
            result = DataFrame(values, index=key_index, columns=[self._selection])
            self._insert_inaxis_grouper_inplace(result)
            return result
    else:
        # values are Series
        return self._wrap_applied_output_series(
            keys, values, not_indexed_same, first_not_none, key_index
        )


# Traceback (KeyError)
Empty DataFrame
Columns: []
Index: []
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/pandas/core/frame.py", line 2927, in __getitem__
indexer = self.columns.get_loc(key)
File "/usr/local/lib/python2.7/dist-packages/pandas/core/indexes/base.py", line 2659, in get_lo
return self._engine.get_loc(self._maybe_cast_indexer(key))
File "pandas/_libs/index.pyx", line 108, in pandas._libs.index.IndexEngine.get_loc
File "pandas/_libs/index.pyx", line 132, in pandas._libs.index.IndexEngine.get_loc
File "pandas/_libs/hashtable_class_helper.pxi", line 1601, in pandas._libs.hashtable.PyObjectHashTable.get_item
File "pandas/_libs/hashtable_class_helper.pxi", line 1608, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 'b'

# Fixed code
def _wrap_applied_output(self, data, keys, values, not_indexed_same=False):
    if len(keys) == 0:
        result = self.obj._constructor(
            index=self.grouper.result_index, columns=data.columns
        )
        result = result.astype(data.dtypes.to_dict(), copy=False)
        return result

    # GH12824
    first_not_none = next(com.not_none(*values), None)

    if first_not_none is None:
        # GH9684 - All values are None, return an empty frame.
        return self.obj._constructor()
    elif isinstance(first_not_none, DataFrame):
        return self._concat_objects(keys, values, not_indexed_same=not_indexed_same)

    key_index = self.grouper.result_index if self.as_index else None

    if isinstance(first_not_none, (np.ndarray, Index)):
        # GH#1738: values is list of arrays of unequal lengths
        #  fall through to the outer else clause
        # TODO: sure this is right?  we used to do this
        #  after raising AttributeError above
        return self.obj._constructor_sliced(
            values, index=key_index, name=self._selection_name
        )
    elif not isinstance(first_not_none, Series):
        # values are not series or array-like but scalars
        # self._selection_name not passed through to Series as the
        # result should not take the name of original selection
        # of columns
        if self.as_index:
            return self.obj._constructor_sliced(values, index=key_index)
        else:
            result = DataFrame(values, index=key_index, columns=[self._selection])
            self._insert_inaxis_grouper_inplace(result)
            return result
    else:
        # values are Series
        return self._wrap_applied_output_series(
            keys, values, not_indexed_same, first_not_none, key_index
        )