Jeremy W. Sherman

stay a while, and listen

Use jsonlint to debug bogus JSON data

NSJSONSerialization delights in an opaque “lolnope character 12341234” error message that provides zero context. It doesn’t even bother to take advantage of line numbers to help you out, even if the JSON data has linebreaks. This is a royal pain, especially if you’re working with hand-written stub data for a web service.

I got fed up with this, went “there has to be a linter!”, and landed on jsonlint by Zach Carter.

Install it via npm install jsonlint -g, and you’ll be able to find and fix syntax errors in JSON far faster than you would puzzling over NSJSONSerialization’s error message.

Comparing Parser Error Messages

Sample Data

Bogus JSON:

bogus.json
1
2
3
4
5
6
7
8
9
{
    "something": "bogus",
    "this way": [{
        "comes"
    ],
    "don't you": "know",
    "ayup": "you do",
    "or you will": "soon"
}

NSJSONSerialization

The wonderfully useless NSJSONSerialization error:

1
2
3
4
5
6
7
8
9
10
11
12
13
% nush
Nu Shell.
% (NSJSONSerialization JSONObjectWithData:
    (NSData dataWithContentsOfFile:"bogus.json")
  options:0 error:(set e (NuReference new)))
()
% ((e value) description)
"Error Domain=NSCocoaErrorDomain Code=3840
\"The data couldn\u2019t be read because it isn\u2019t in the correct format.\"
(No value for key in object around character 67.)
UserInfo=0x7fbf2860e8b0 {NSDebugDescription=No value for key in object
around character 67.}"
% (exit)

Python

The equally useless Python json error:

1
2
3
4
5
6
7
8
9
10
% python
Python 2.7.6 (default, Dec 28 2013, 00:41:57)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> json.load(file("bogus.json"))
Traceback (most recent call last):
    # 8< snipped 8<
ValueError: Expecting : delimiter: line 5 column 5 (char 67)
>>>

Hey, at least Python takes advantage of the fact the file has line numbers.

jsonlint

The jsonlint output:

1
2
3
4
5
% jsonlint bogus.json
[Error: Parse error on line 4:
...        "comes"    ],    "don't you":
----------------------^
Expecting ':', got ']']

Now, isn’t that nice? No need to cross-reference to the file, since there’s context right there, and you know exactly what it’s expecting, rather than just some opaque “delimiter”.

(The Cocoa error in this example isn’t entirely useless, since it does call out that a key is missing its value. I’ve seen more useless ones where it faults the very end of the file for something that went wrong way earlier.)

Installing jsonlint

I’ve installed it locally using npm install jsonlint -g.

Apparently, you could also use http://jsonlint.com/, but:

  • I’m wary of posting potentially sensitive JSON data to a public web service
  • I like being able to work even without network access
  • command-line tools compose easily into pipe-lines far better than most websites

So, I naturally recommend you just install it locally.