Why does there exist Json.undefined in vibe.data.json package?

Possibly because null is a reserved keyword for D and can't be used as a custom object state.

It seems odd that a non-existing field test in j is not undefined, and is not equal to undefined, though its type is equal to Json.Type.undefined.

It should be specified in the docs, but I always use .to! on the Json object to verify its validity.

auto j = Json.emptyObject;assert(j.test.to!bool == false);assert(j.test.to!string == "undefined");

The reason being that comparing two Json objects with is will only compare the underlying pointers of two different pointers, it's a low-level feature of D that lets you "shoot yourself in the foot".

I agree though that j.test == Json.undefined should work as an exception, but I can't think of a way of making this happen because Json.undefined returns Json.init. The way opEquals is implented now for undefined is inspired by NaN from real, where two undefined variables can never be equal, as to avoid j.foo == j.bar returning true if they are undefined.