The cause was identified in this answer.
But instead of
try:
ctype = ctype.encode(default_encoding) # omit in 3.x!
except UnicodeEncodeError:
pass
you may try, because it is a DecodeError after all:
try:
ctype = ctype.encode(default_encoding) # omit in 3.x!
except UnicodeEncodeError, UnicodeDecodeError:
pass
It is likely to happen in a multibyte encoding system. In this case, there is a mime type in registry contains multi-byte char. Python figured out it is an ascii string (which is wrong, that is why you see the ascii decode error) and tried to convert to Python's internal string representation before it actually do the encoding stuff. Then it sorrows with the UnicodeDecodeError exception. There is no UnicodeEncodeEorror yet at this point.
To make the whole internal process clear, you can explicitly convert ctype to unicode to make it continue to the encode stage, like
ctype = unicode(ctype, youractualencoding).encode(default_encoding)
Then it will (probably) throw the UnicodeEncodeError here, because the default_encoding is ascii in this scenario which cannot handle multi-byte character (This is also the reason it fails in the first place). So we need to handle both UnicodeEncodeError and UnicodeDecodeError.
Now you see what is going on here. IPython notebook was trying to load external resources like custom.js. It looks into the registry to find out the content type. Then it gets choked up by the exotic mime type.