{"record":{"id":"0979f62710fd933b","repo":"affaan-m/ECC","slug":"application-request-must-be-a-json-object","errorCode":null,"errorMessage":"application request must be a JSON object","messagePattern":"application request must be a JSON object","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/integration.py","lineNumber":166,"sourceCode":"                or _identity(before) != _identity(after)):\n            raise ValueError(\"artifact changed during reading\")\n        if expected_hash is not None and digest.hexdigest() != expected_hash:\n            raise ValueError(\"artifact SHA-256 mismatch\")\n        return _load_json(b\"\".join(chunks)) if parse_json else None\n    except (OSError, AttributeError) as exc:\n        raise ValueError(\"local artifact unavailable or unsafe\") from exc\n    finally:\n        if descriptor is not None:\n            os.close(descriptor)\n        if parent is not None:\n            os.close(parent)\n\n\ndef load_application_request(path: str | Path) -> dict:\n    \"\"\"Load only a bounded resident request; never follow a config symlink.\"\"\"\n    value = _read_local(str(Path(path).absolute()), parse_json=True)\n    if not isinstance(value, dict):\n        raise ValueError(\"application request must be a JSON object\")\n    return value\n\n\ndef _load_json(data: bytes) -> Any:\n    def unique(pairs):\n        result = {}\n        for key, value in pairs:\n            if key in result:\n                raise ValueError(\"duplicate JSON field\")\n            result[key] = value\n        return result\n\n    try:\n        value = json.loads(data, object_pairs_hook=unique)\n        _canonical(value)\n        return value\n    except (UnicodeError, RecursionError) as exc:\n        raise ValueError(\"invalid JSON artifact\") from exc","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/integration.py#L148-L184","documentation":"load_application_request() reads a local JSON file and requires the top-level parsed value to be a JSON object (dict). The library throws this because the whole request model (baseline, source, candidates, inserts) is keyed-field based; an array, string, number or null at the top level cannot carry the required fields, so it fails fast instead of raising confusing downstream errors.","triggerScenarios":"Calling load_application_request(path) where the file contains valid JSON whose top-level value is not an object — e.g. a bare JSON array `[...]`, a quoted string, a number, `true`, or `null`.","commonSituations":"Hand-edited request files that start with a list of baselines; a script that dumps `json.dumps(items)` of a list instead of wrapping it in an object; exporting only the `candidates` array; a tool writing `null` on an empty export.","solutions":["Wrap the file's top-level content in a JSON object with the required keys (baseline, source, audio, protected_intervals).","Check the first non-whitespace character of the file: `[`, `\"`, a digit, or `null`/`true`/`false` means it is not an object — fix the producer.","Regenerate the request via whatever upstream tool compiles the full application config, not a partial export.","If you only have the inner payload, embed it: {\"baseline\": ..., \"source\": ..., ...} before passing the path."],"exampleFix":"// before (request.json)\n[{\"baseline\": {...}}, ...]\n\n// after\n{\"baseline\": {...}, \"source\": {...}, \"audio\": [], \"protected_intervals\": [...]}","handlingStrategy":"validation","validationCode":"import json\ndef ensure_json_object(path):\n    with open(path, encoding=\"utf-8\") as f:\n        value = json.load(f)\n    if not isinstance(value, dict):\n        raise TypeError(f\"{path}: top-level JSON must be an object, got {type(value).__name__}\")\n    return value","typeGuard":"def is_json_object(value) -> bool:\n    return isinstance(value, dict)","tryCatchPattern":"try:\n    request = load_application_request(path)\nexcept ValueError as exc:\n    if \"must be a JSON object\" in str(exc):\n        print(f\"{path}: top level must be {{...}} — fix the producer\")\n    raise","preventionTips":["Always serialize the full config object, never a bare list.","Lint request files with a schema checker before invoking the library.","Keep the first character of request files as '{'.","Add a CI check that json.load's each request file and asserts isinstance dict."],"tags":["json","validation","input"],"backgroundTag":"type-mismatch","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}