One way to make setting the root work in practice would be to return the entire modified object instead of the old node value, and suggest that the caller use that. Then it would make sense to get rid of the exception message.
Now that I think about it, I'm not crazy about the exception on set. I'm going to add another commit to remove that exception.
add failing test (complex keys)
unescape parts of the path
handle root references
just return old value instead of set exception