My choice is to raise an error, and I made Gauche's json library do so. However, I could think the a case of treating it as a non-unicode codepoint---when you have to deal with existing JSON files that contains such strings. For example, if you read such JSON, add one field to it and write it out, using replacement character is out of option since it loses the information.
I don't know how much such 'sloppy' JSON is in the wild. I once worked on emails and there were so many broken emails that libraries that rejected them weren't usable. I guess it depends on how bad the actual situation is. We can say "it is an error to have unpaired surrogates", and leave the interpretation of "error" to each implementation.