3

While working with JSON in Emacs Lisp, I got an error json-encode-key: Bad JSON object key: t. It made sense to me that the key was "t" but not necessarily why, or what I can do about it.

The following code sample reproduces this scenario:

(let ((foo (json-read-from-string "{\"t\":42}")))
  (message "%s" foo)                  ; ((t . 42))
  (message "%s" (json-encode foo)))   ; json-encode-key: Bad JSON object key: t

How can I work around this, given that the JSON in question involves a key of "t"?

2

This is a well-known long-standing bug in json.el that has been fixed in the latest development version of Emacs (what will be released in the future as Emacs 28): https://bugs.gnu.org/42545

If you don't have access to the development version of Emacs, but have an Emacs 27 built with native JSON support (i.e. configured --with-json to link against the Jansson library, which is the default on systems where this library is available), then you can use the new native (and faster) functions in place of their json.el counterparts:

(let ((foo (json-parse-string "{\"t\":42}" :object-type 'alist)))
  (message "%s" foo)                    ; ((t . 42))
  (message "%s" (json-serialize foo)))  ; {"t":42}

See (info "(elisp) Parsing JSON") for more on this.

Otherwise, the only workaround for this bug is to avoid objects that have confusable keys such as the symbol t. If you generate the data, then happy days: the fix is as simple as using a different object or key type that isn't as ambiguous, for example:

(let* ((json-object-type 'hash-table)
       (foo (json-read-from-string "{\"t\":42}")))
  (message "%s" foo)                ; #s(hash-table ...)
  (message "%s" (json-encode foo))) ; {"t":42}

(let* ((json-key-type 'keyword)
       (foo (json-read-from-string "{\"t\":42}")))
  (message "%s" foo)                ; ((:t . 42))
  (message "%s" (json-encode foo))) ; {"t":42}

For more on this, have a read through the variables defined at the top of M-x find-library RET json RET.

If you don't generate the data, then you will probably need to sanitise it first.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.