Json dumping a dict throws TypeError: keys must be a string

Modifying the accepted answer above, I wrote a function to handle dictionaries of arbitrary depth:

def stringify_keys(d):
    """Convert a dict's keys to strings if they are not."""
    for key in d.keys():

        # check inner dict
        if isinstance(d[key], dict):
            value = stringify_keys(d[key])
        else:
            value = d[key]

        # convert nonstring to string if needed
        if not isinstance(key, str):
            try:
                d[str(key)] = value
            except Exception:
                try:
                    d[repr(key)] = value
                except Exception:
                    raise

            # delete old key
            del d[key]
    return d

I know this is an old question and it already has an accepted answer, but alas the accepted answer is just totally wrong.

The real issue here is that the code that generates the dict uses the builtin id function as key instead of the literal string "id". So the simple, obvious and only correct solution is to fix this bug at the source : check the code that generates the dict, and replace id with "id".


You could try to clean it up like this:

for key in mydict.keys():
  if type(key) is not str:
    try:
      mydict[str(key)] = mydict[key]
    except:
      try:
        mydict[repr(key)] = mydict[key]
      except:
        pass
    del mydict[key]

This will try to convert any key that is not a string into a string. Any key that could not be converted into a string or represented as a string will be deleted.