enforce: certain DSL elements may appear only 1x

add `CaskInvalidError` exception, which ought to be used in
several other places as well