langchain-ai/deepagents · error
Plugin id {self.plugin_id!r} does not match {expected!r}
Error message
Plugin id {self.plugin_id!r} does not match {expected!r} What it means
Plugin dataclass instances enforce the invariant plugin_id == f"{name}@{marketplace}" in __post_init__. Constructing a Plugin whose id string disagrees with its name and marketplace fields raises ValueError, because derived caches and lookups (split_plugin_id) rely on the canonical id format.
Source
Thrown at libs/code/deepagents_code/plugins/models.py:129
plugin_id: str
name: str
marketplace: str
version: str | None
root: Path
data_dir: Path
manifest: PluginManifest | None
inventory: ComponentInventory
def __post_init__(self) -> None:
"""Validate the canonical plugin identity.
Raises:
ValueError: If `plugin_id` disagrees with `name` and `marketplace`.
"""
expected = f"{self.name}@{self.marketplace}"
if self.plugin_id != expected:
msg = f"Plugin id {self.plugin_id!r} does not match {expected!r}"
raise ValueError(msg)
@dataclass(frozen=True, slots=True, kw_only=True)
class LocalPluginSource:
"""A plugin stored relative to its marketplace."""
source_type: Literal["local"]
path: str
@dataclass(frozen=True, slots=True, kw_only=True)
class GithubPluginSource:
"""A plugin sourced from a GitHub repository."""
source_type: Literal["github"]
repo: str
ref: str | None = None
path: str | None = NoneView on GitHub (pinned to a1af029e6e)
Solutions
- Set plugin_id to exactly f'{name}@{marketplace}' or omit it if the constructor derives it.
- Rename the marketplace in both the marketplace config and plugin_id together.
- Fix the source record (state/cache) so its stored id matches name@marketplace.
Example fix
// before Plugin(name='lint', marketplace='team', plugin_id='lint@other') // after Plugin(name='lint', marketplace='team', plugin_id='lint@team')
Defensive patterns
Strategy: validation
Validate before calling
def build_plugin_id(name: str, marketplace: str) -> str:
pid = f"{name}@{marketplace}"
assert pid == f"{name}@{marketplace}"
return pid
# construct via helper so id and fields can never drift Type guard
def id_matches(pid: str, name: str, marketplace: str) -> bool:
return pid == f"{name}@{marketplace}" Try / catch
try:
plugin = Plugin(**fields)
except ValueError as exc:
if "does not match" in str(exc):
fields["plugin_id"] = f"{fields['name']}@{fields['marketplace']}"
plugin = Plugin(**fields) Prevention
- Always derive plugin_id from name and marketplace with an f-string; never hardcode it.
- When renaming a marketplace, rewrite plugin_id wherever it is persisted.
- Add a unit test asserting the invariant for every Plugin you construct.
When it happens
Trigger: Constructing Plugin(name='a', marketplace='m', plugin_id='a@other') or passing plugin_id=None/wrong separator while name/marketplace imply a different id; deserializing a plugin record written by an older format.
Common situations: Hand-building Plugin objects in tests or scripts with inconsistent fields; migrating state files where marketplace was renamed but cached plugin_id was not; forgetting '@' in a manually composed plugin_id.
Related errors
- ColdCacheWarning age_seconds={self.age_seconds!r} does not p
- `unreadable_reason` implies the token is not usable; `logged
- shell_allow_list must be None or non-empty
- goal application requires a non-empty objective and rubric
- RewarmEstimate costs must be finite, got cold={self.cold_cos
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/e8ce9a5415494332.
Report an issue: GitHub.