{"record":{"id":"b53582a0f530a2c6","repo":"langchain-ai/deepagents","slug":"invalid-plugin-id-plugin-id-r-expected-name-mar","errorCode":null,"errorMessage":"Invalid plugin id {plugin_id!r}; expected name@marketplace","messagePattern":"Invalid plugin id (.+?); expected name@marketplace","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/plugins/models.py","lineNumber":242,"sourceCode":"class PluginDiscoveryResult:\n    \"\"\"Result from plugin discovery.\"\"\"\n\n    plugins: tuple[PluginInstance, ...]\n    warnings: tuple[str, ...] = ()\n\n\ndef split_plugin_id(plugin_id: str) -> tuple[str, str]:\n    \"\"\"Split a plugin id in `{plugin}@{marketplace}` form.\n\n    Returns:\n        Plugin and marketplace names.\n\n    Raises:\n        ValueError: If either part is missing.\n    \"\"\"\n    if \"@\" not in plugin_id:\n        msg = f\"Invalid plugin id {plugin_id!r}; expected name@marketplace\"\n        raise ValueError(msg)\n    plugin, marketplace = plugin_id.rsplit(\"@\", 1)\n    if not plugin or not marketplace:\n        msg = f\"Invalid plugin id {plugin_id!r}; expected name@marketplace\"\n        raise ValueError(msg)\n    return plugin, marketplace\n","sourceCodeStart":224,"sourceCodeEnd":248,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/plugins/models.py#L224-L248","documentation":"split_plugin_id parses the canonical 'name@marketplace' plugin id using rsplit('@', 1). If the id contains no '@' at all, it cannot be split and ValueError is raised with the 'expected name@marketplace' message. Callers include remove_marketplace, discover_plugins, auto_update_plugins, and versioned_cache_path.","triggerScenarios":"Passing a bare plugin name like 'my-plugin' (no @marketplace suffix) to any API that takes a plugin_id — e.g. remove_marketplace/plugin removal paths, discover_plugins, or cache path computation.","commonSituations":"Users typing only the plugin name in a command; old config/state records from before the name@marketplace scheme; composing the id with a different separator like ':' or '/'.","solutions":["Include the marketplace suffix: pass 'name@marketplace' instead of the bare name.","Look up the full id from the loaded marketplace's plugin entries or `plugin.plugin_id`.","Migrate any stored ids from the legacy format to name@marketplace."],"exampleFix":"// before\nremove_plugin('lint')\n// after\nremove_plugin('lint@team-market')","handlingStrategy":"validation","validationCode":"def ensure_plugin_id(pid: str) -> None:\n    if \"@\" not in pid:\n        raise ValueError(f\"{pid!r} must be 'name@marketplace'\")","typeGuard":"def is_valid_plugin_id(pid: object) -> TypeGuard[str]:\n    return isinstance(pid, str) and \"@\" in pid","tryCatchPattern":"try:\n    name, market = split_plugin_id(raw_id)\nexcept ValueError as exc:\n    logger.error(\"Bad plugin id %r: %s\", raw_id, exc)\n    return","preventionTips":["Resolve user-supplied names against the marketplace index to get the full id.","Standardize on the '@' separator in all tooling and scripts.","Validate ids at config-parse time, before calling library APIs."],"tags":["plugin-id","parsing","validation"],"backgroundTag":"invalid-plugin-id-format","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}