langchain-ai/deepagents · error · MarketplaceError

Marketplace URL must return a JSON object: {_redact_url_cred

Error message

Marketplace URL must return a JSON object: {_redact_url_credentials(url)}

What it means

The marketplace catalog downloaded from a URL must be a JSON object (dict) at the top level. If the server returns an array, string, number, or null, the library raises this error because the catalog schema expects keyed fields.

Source

Thrown at libs/code/deepagents_code/plugins/marketplace.py:389

    try:
        with opener.open(request, timeout=10) as response:
            final_url = response.geturl()
            if urlparse(final_url).scheme != "https":
                detail = _redact_url_credentials(final_url)
                msg = f"Marketplace response must use https: {detail}"
                raise MarketplaceError(msg)
            data = json.load(response)
    except (OSError, urllib.error.URLError, json.JSONDecodeError) as exc:
        msg = (
            "Failed to download marketplace from "
            f"{_redact_url_credentials(url)}: {redact_urls_in_text(str(exc))}"
        )
        raise MarketplaceError(msg) from exc
    if not isinstance(data, dict):
        msg = (
            f"Marketplace URL must return a JSON object: {_redact_url_credentials(url)}"
        )
        raise MarketplaceError(msg)
    cache_path.parent.mkdir(parents=True, exist_ok=True)
    cache_path.write_text(
        json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8"
    )
    return cache_path


def materialize_marketplace_source(
    source: MarketplaceSource,
) -> tuple[PluginMarketplace, Path]:
    """Load a marketplace source and return its local install location.

    Args:
        source: Parsed marketplace source.

    Returns:
        Parsed marketplace and its local install location.

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Make the endpoint return a top-level JSON object matching the marketplace schema ({"plugins": [...] , ...})
  2. Point the URL at the actual catalog file rather than an API or index endpoint
  3. Wrap the data: if you currently return [ ... ], return {"plugins": [ ... ]} per the expected schema

Example fix

// before
[ {"name": "foo"} ]
// after
{
  "plugins": [ {"name": "foo"} ]
}
Defensive patterns

Strategy: validation

Validate before calling

import urllib.request, json
with urllib.request.urlopen(marketplace_url) as r:
    data = json.load(r)
if not isinstance(data, dict):
    raise ValueError("marketplace catalog must be a JSON object")

Type guard

from typing import Any
def is_marketplace_dict(data: Any) -> bool:
    return isinstance(data, dict)

Try / catch

try:
    marketplace, path = materialize_marketplace_source(source)
except MarketplaceError as exc:
    if "must return a JSON object" in str(exc):
        log.error("Catalog at URL has wrong top-level JSON shape")
    raise

Prevention

When it happens

Trigger: _download_marketplace successfully fetched and parsed the response, but json.load produced a non-dict value — e.g. a top-level JSON array or scalar.

Common situations: Serving a plain list of plugins instead of the full catalog object; pointing the URL at an endpoint that returns a different JSON shape (API metadata, health check); a marketplace file exported in the wrong format.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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