Top-level fields are parsed as the shared config; an optional modules { … } object maps each module key to its own per-module config (parsed with the same logic). Errors from the shared parse and every module parse are collected into one "; "-joined message.