# Buggy code
def write(fname, data, header, **kwargs):
    """
    Take a data header pair and write a FITS file.

    Parameters
    ----------
    fname : `str`
        File name, with extension

    data : `numpy.ndarray`
        n-dimensional data array

    header : `dict`
        A header dictionary
    """
    # Copy header so the one in memory is left alone while changing it for
    # write.
    header = header.copy()

    # The comments need to be added to the header separately from the normal
    # kwargs. Find and deal with them:
    fits_header = fits.Header()
    # Check Header
    key_comments = header.pop("KEYCOMMENTS", False)

    for k, v in header.items():
        if isinstance(v, fits.header._HeaderCommentaryCards):
            if k == "comments":
                comments = str(v).split("\n")
                for com in comments:
                    fits_header.add_comments(com)
            elif k == "history":
                hists = str(v).split("\n")
                for hist in hists:
                    fits_header.add_history(hist)
            elif k != "":
                fits_header.append(fits.Card(k, str(v).split("\n")))

        else:
            fits_header.append(fits.Card(k, v))

    if isinstance(key_comments, dict):
        for k, v in key_comments.items():
            fits_header.comments[k] = v
    elif key_comments:
        raise TypeError("KEYCOMMENTS must be a dictionary")

    if isinstance(fname, str):
        fname = os.path.expanduser(fname)

    fitskwargs = {"output_verify": "fix"}
    fitskwargs.update(kwargs)
    fits.writeto(fname, data, header=fits_header, **fitskwargs)


# Traceback (KeyError)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-260-752b35ded2b2> in <module>()
----> 1 aia_sub.save("test.fits")

~/miniconda/lib/python3.6/site-packages/sunpy/map/mapbase.py in save(self, filepath, filetype, **kwargs)
930         """
931         io.write_file(filepath, self.data, self.meta, filetype=filetype,
--> 932                       **kwargs)
933
934 # #### Image processing routines #### #

~/miniconda/lib/python3.6/site-packages/sunpy/io/file_tools.py in write_file(fname, data, header, filetype, **kwargs)
155         for extension, readername in _known_extensions.items():
156             if fname.endswith(extension):
--> 157                 return _readers[readername].write(fname, data, header, **kwargs)
158
159     else:

~/miniconda/lib/python3.6/site-packages/sunpy/io/fits.py in write(fname, data, header, **kwargs)
197     if isinstance(key_comments, dict):
198         for k, v in key_comments.items():
--> 199             fits_header.comments[k] = v
200     elif key_comments:
201         raise TypeError("KEYCOMMENTS must be a dictionary")

~/miniconda/lib/python3.6/site-packages/astropy/io/fits/header.py in __setitem__(self, item, comment)
2030         # In this case, key/index errors should be raised; don't update
2031         # comments of nonexistent cards
-> 2032         idx = self._header._cardindex(item)
2033         value = self._header[idx]
2034         self._header[idx] = (value, comment)

~/miniconda/lib/python3.6/site-packages/astropy/io/fits/header.py in _cardindex(self, key)
1652
1653         if not indices:
-> 1654             raise KeyError("Keyword {!r} not found.".format(keyword))
1655
1656         try:

KeyError: "Keyword 'CROTA2' not found."

# Fixed code
def write(fname, data, header, **kwargs):
    """
    Take a data header pair and write a FITS file.

    Parameters
    ----------
    fname : `str`
        File name, with extension

    data : `numpy.ndarray`
        n-dimensional data array

    header : `dict`
        A header dictionary
    """
    # Copy header so the one in memory is left alone while changing it for
    # write.
    header = header.copy()

    # The comments need to be added to the header separately from the normal
    # kwargs. Find and deal with them:
    fits_header = fits.Header()
    # Check Header
    key_comments = header.pop("KEYCOMMENTS", False)

    for k, v in header.items():
        if isinstance(v, fits.header._HeaderCommentaryCards):
            if k == "comments":
                comments = str(v).split("\n")
                for com in comments:
                    fits_header.add_comments(com)
            elif k == "history":
                hists = str(v).split("\n")
                for hist in hists:
                    fits_header.add_history(hist)
            elif k != "":
                fits_header.append(fits.Card(k, str(v).split("\n")))

        else:
            fits_header.append(fits.Card(k, v))

    if isinstance(key_comments, dict):
        for k, v in key_comments.items():
            # Check that the Card for the comment exists before trying to write to it.
            if k in fits_header:
                fits_header.comments[k] = v
    elif key_comments:
        raise TypeError("KEYCOMMENTS must be a dictionary")

    if isinstance(fname, str):
        fname = os.path.expanduser(fname)

    fitskwargs = {"output_verify": "fix"}
    fitskwargs.update(kwargs)
    fits.writeto(fname, data, header=fits_header, **fitskwargs)