langchain-ai/deepagents · error · TypeError

hooks trust store projects must be an object: {path}

Error message

hooks trust store projects must be an object: {path}

What it means

The hooks trust store file's "projects" key must map project paths to trust entry objects. _parse_projects raises TypeError when the parsed JSON has a non-object at that position (e.g. a list or string), naming the offending store path, because per-project trust cannot be read from any other shape.

Source

Thrown at libs/code/deepagents_code/hooks/trust.py:125

    """Parse trust entries, skipping structurally invalid ones.

    Args:
        raw_projects: Raw `projects` value from JSON.
        path: Store path used in warning messages.

    Returns:
        Validated project map. Empty when `raw_projects` is missing or not a
        mapping.

    Raises:
        TypeError: When `raw_projects` is present but not a mapping (strict
            callers refuse to overwrite such stores).
    """
    if raw_projects is None:
        return {}
    if not isinstance(raw_projects, dict):
        msg = f"hooks trust store projects must be an object: {path}"
        raise TypeError(msg)

    projects: dict[str, HooksTrustEntry] = {}
    for key, value in raw_projects.items():
        if not isinstance(key, str):
            logger.warning(
                "Skipping non-string hooks trust project key in %s: %r",
                path,
                key,
            )
            continue
        try:
            projects[key] = HooksTrustEntry.model_validate(value)
        except ValidationError as exc:
            logger.warning(
                "Skipping invalid hooks trust entry for %s in %s: %s",
                key,
                path,
                exc,

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Fix the store file so "projects" is a JSON object: {"projects": {"/path/to/project": {...entry...}}}.
  2. Delete the corrupted store and let the library recreate it, then re-approve trust via the trust flow (trust_project_hooks).
  3. Back up the file before editing and validate JSON shape after edits.
  4. Catch TypeError at load time and prompt the user to re-trust rather than crashing.

Example fix

// before
{"version": 1, "projects": ["/repo/a"]}   // list -> TypeError

// after
{"version": 1, "projects": {"/repo/a": {"trusted_at": "2026-01-01T00:00:00Z"}}}
Defensive patterns

Strategy: validation

Validate before calling

data = json.loads(store_path.read_text())
if not isinstance(data.get("projects", {}), dict):
    repair_or_reset_store(store_path)

Type guard

def has_valid_projects(data: object) -> TypeGuard[dict]:
    return isinstance(data, dict) and isinstance(data.get("projects", {}), dict)

Try / catch

try:
    store = load_hooks_trust_store(path)
except TypeError as exc:
    if "must be an object" in str(exc):
        backup_and_reset_store(path)  # recreate + re-trust

Prevention

When it happens

Trigger: Loading a trust store whose top-level JSON is an object but whose "projects" field is a list, string, number, or null-typed non-dict (raw_projects not None and not a dict) during _load_store -> _parse_projects.

Common situations: Hand-editing the trust store JSON and writing projects as an array; a migration or older tool writing the legacy flat format; corruption by concurrent writes or editors.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/d48f6c8ee52d08ce. Report an issue: GitHub.