langchain-ai/deepagents · error · MarketplaceError

{unresolved_source_message(plugin_id, entry, rejections)}

Error message

{unresolved_source_message(plugin_id, entry, rejections)}

What it means

install_plugin materializes the plugin's source from the marketplace into a local root; when materialize_plugin_source returns None it populates `rejections` explaining why candidate sources were rejected, and install_plugin raises MarketplaceError with unresolved_source_message summarizing them. It means no valid local copy of the plugin source could be produced from the marketplace entry.

Source

Thrown at libs/code/deepagents_code/plugins/discovery.py:226

    writes `installed_plugins.json`, and enables the plugin.

    Args:
        plugin_id: Plugin id in `{name}@{marketplace}` form.

    Returns:
        Discovered plugin instance loaded from the cache path.

    Raises:
        MarketplaceError: If the marketplace/plugin cannot be resolved, the
            source is unsupported, or the cached plugin fails to load.
    """
    load_installed_plugins(strict=True)
    load_enabled_plugin_ids(strict=True)
    marketplace, entry = _resolve_marketplace_and_entry(plugin_id)
    rejections: list[str] = []
    source_root = materialize_plugin_source(marketplace, entry, rejections=rejections)
    if source_root is None:
        raise MarketplaceError(unresolved_source_message(plugin_id, entry, rejections))

    try:
        manifest, _manifest_path, manifest_warnings = load_manifest(
            source_root, fallback_name=entry.name
        )
    except PluginManifestError as exc:
        msg = f"Cannot install {plugin_id}: {exc}"
        raise MarketplaceError(msg) from exc

    for warning in manifest_warnings:
        logger.debug("Plugin install warning for %s: %s", plugin_id, warning)

    version = manifest.version if manifest is not None else None
    cache_path = cache_and_register_plugin(
        plugin_id,
        source_root,
        version=version,
        validate=partial(

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Read the unresolved_source_message — the embedded rejections name each rejected source and reason.
  2. Re-add or refresh the marketplace so its source location is intact and current.
  3. Remove forbidden symlinks (or point them inside the plugin) in the plugin source.
  4. Check the cache/install directories for permissions and disk space.
  5. If the source lives remotely, verify the fetch (URL reachable, credentials valid) then retry.

Example fix

// before (plugin dir contains a symlink escaping the plugin)
src -> /usr/share/evil   # rejected
# after
ln -s ./vendor src       # symlink stays inside the plugin
$ dcode plugin install widget@internal
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def source_root_sane(root: Path) -> bool:
    if not root.is_dir():
        return False
    for link in root.rglob("*"):
        if link.is_symlink():
            target = link.resolve()
            if not target.is_relative_to(root.resolve()):
                return False  # symlink escapes plugin dir -> will be rejected
    return True

assert source_root_sane(Path("plugins/widget"))

Type guard

def symlink_safe(root: Path) -> bool:
    root_resolved = root.resolve()
    return all(
        not p.is_symlink() or p.resolve().is_relative_to(root_resolved)
        for p in root.rglob("*")
    )

Try / catch

try:
    install_plugin("widget@internal")
except MarketplaceError as exc:
    print("source unresolved:", exc)  # rejections list explains each rejected candidate
    # remediate: refresh marketplace, fix symlinks, check disk/permissions

Prevention

When it happens

Trigger: materialize_plugin_source fails for all candidate sources — e.g. checkout/copy refused (symlink escaping the plugin directory, missing files), cache write failure, or the marketplace entry pointing at a nonexistent source path; the rejections list is embedded in the message.

Common situations: A plugin repo containing symlinks that point outside the plugin (deliberately rejected for safety); a marketplace install_location deleted or moved on disk; partial/corrupted marketplace checkout; network fetch failures during materialization.

Related errors


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