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.