@@ -222,9 +222,31 @@ ParseResult ConfigReader::ParseConfig(const std::string_view& config_path) {
222222 return ParseResult::FileError;
223223 }
224224
225- // Validate against JSON Schema before parsing options.
226- // ata works on the raw string independently of simdjson,
227- // so no re-parse is needed.
225+ // Parse the configuration file
226+ simdjson::ondemand::parser json_parser;
227+ simdjson::ondemand::document document;
228+ if (json_parser.iterate(file_content).get (document)) {
229+ FPrintF (stderr, " Can't parse %s\n " , config_path.data ());
230+ return ParseResult::InvalidContent;
231+ }
232+
233+ // Validate config is an object
234+ simdjson::ondemand::object main_object;
235+ auto root_error = document.get_object ().get (main_object);
236+ if (root_error) {
237+ if (root_error == simdjson::error_code::INCORRECT_TYPE) {
238+ FPrintF (stderr,
239+ " Root value unexpected not an object for %s\n\n " ,
240+ config_path.data ());
241+ } else {
242+ FPrintF (stderr, " Can't parse %s\n " , config_path.data ());
243+ }
244+ return ParseResult::InvalidContent;
245+ }
246+
247+ // Validate against JSON Schema after basic parsing succeeds.
248+ // This catches type errors in properties before the option
249+ // parsing loop, which would otherwise produce less clear messages.
228250 {
229251 auto schema = ata::compile (kNodeConfigSchema );
230252 if (schema) {
@@ -249,28 +271,6 @@ ParseResult ConfigReader::ParseConfig(const std::string_view& config_path) {
249271 }
250272 }
251273
252- // Parse the configuration file
253- simdjson::ondemand::parser json_parser;
254- simdjson::ondemand::document document;
255- if (json_parser.iterate(file_content).get (document)) {
256- FPrintF (stderr, " Can't parse %s\n " , config_path.data ());
257- return ParseResult::InvalidContent;
258- }
259-
260- // Validate config is an object
261- simdjson::ondemand::object main_object;
262- auto root_error = document.get_object ().get (main_object);
263- if (root_error) {
264- if (root_error == simdjson::error_code::INCORRECT_TYPE) {
265- FPrintF (stderr,
266- " Root value unexpected not an object for %s\n\n " ,
267- config_path.data ());
268- } else {
269- FPrintF (stderr, " Can't parse %s\n " , config_path.data ());
270- }
271- return ParseResult::InvalidContent;
272- }
273-
274274 // Get all available namespaces for validation
275275 std::vector<std::string> available_namespaces =
276276 options_parser::MapAvailableNamespaces ();
0 commit comments