{"record":{"id":"becd909007e7911c","repo":"langchain-ai/deepagents","slug":"plugin-manifest-manifest-path-must-be-a-json-obj","errorCode":null,"errorMessage":"Plugin manifest {manifest_path} must be a JSON object","messagePattern":"Plugin manifest (.+?) must be a JSON object","errorType":"exception","errorClass":"PluginManifestError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/plugins/manifest.py","lineNumber":284,"sourceCode":"        `(manifest, manifest_path, warnings)`.\n\n    Raises:\n        PluginManifestError: If the manifest exists but is invalid.\n    \"\"\"\n    manifest_path = find_manifest_path(root)\n    if manifest_path is None:\n        return None, None, ()\n    try:\n        decoded = json.loads(manifest_path.read_text(encoding=\"utf-8\"))\n    except json.JSONDecodeError as exc:\n        msg = f\"Invalid JSON syntax in {manifest_path}: {exc}\"\n        raise PluginManifestError(msg) from exc\n    except OSError as exc:\n        msg = f\"Could not read plugin manifest {manifest_path}: {exc}\"\n        raise PluginManifestError(msg) from exc\n    if not isinstance(decoded, dict):\n        msg = f\"Plugin manifest {manifest_path} must be a JSON object\"\n        raise PluginManifestError(msg)\n    raw = json_object(decoded)\n\n    warnings: list[str] = []\n    name = _validate_name(raw.get(\"name\"), fallback=fallback_name)\n    component_paths: dict[str, tuple[Path, ...]] = {}\n    for field_name in _PATH_COMPONENT_FIELDS:\n        declaration = raw.get(field_name)\n        if declaration is None:\n            continue\n        if field_name in {\"mcpServers\", \"hooks\"} and isinstance(declaration, dict):\n            continue\n        paths = _resolve_component_paths(declaration, root, field_name, warnings)\n        if paths:\n            component_paths[field_name] = paths\n\n    version_value = raw.get(\"version\")\n    version = version_value if isinstance(version_value, str) else None\n    display_name_value = raw.get(\"displayName\")","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/plugins/manifest.py#L266-L302","documentation":"After successfully parsing the manifest JSON, `load_manifest` requires the decoded value to be a JSON object (dict). If the file parses but contains a list, string, number, or `null`, this `PluginManifestError` is raised — the manifest schema is object-shaped (`name`, `version`, component path fields).","triggerScenarios":"`load_manifest` is called on a plugin root whose manifest file contains valid JSON that is not an object — e.g. a top-level array, a bare quoted string, or `null`.","commonSituations":"Author wrapped the manifest in an array `[ {...} ]`; file accidentally contains only a version string; a generator/export tool emitted a JSON list of manifests instead of one object.","solutions":["Reshape the manifest to a top-level JSON object with fields like `name`, `version`, and component paths.","If it's a list of manifests, split into one object per plugin directory.","Validate with `python -c \"import json,sys; d=json.load(open('plugin.json')); assert isinstance(d, dict)\"` before publishing."],"exampleFix":"// before\n[{\"name\": \"x\", \"version\": \"1.0\"}]\n// after\n{\"name\": \"x\", \"version\": \"1.0\"}","handlingStrategy":"type-guard","validationCode":"import json\nfrom pathlib import Path\nd = json.loads(Path(\"plugin.json\").read_text(encoding=\"utf-8\"))\nassert isinstance(d, dict), \"manifest must be a JSON object, not a list/string\"","typeGuard":"def is_manifest_object(decoded: object) -> bool:\n    return isinstance(decoded, dict)","tryCatchPattern":"try:\n    manifest, _, _ = load_manifest(root)\nexcept PluginManifestError as exc:\n    if \"must be a JSON object\" in str(exc):\n        print(f\"reshape manifest to a top-level object: {exc}\")","preventionTips":["A manifest is always a single JSON object — never an array of objects.","If a generator emits lists, write one object per plugin directory.","Type-check the parsed document before saving manifests in tooling."],"tags":["plugins","manifest","json","schema"],"backgroundTag":"manifest-schema-invalid","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}