{"record":{"id":"d56ebca005892c7f","repo":"langchain-ai/deepagents","slug":"extra-extra-r-is-not-installed-selected-extras","errorCode":null,"errorMessage":"Extra {extra!r} is not installed. Selected extras: {listed}","messagePattern":"Extra (.+?) is not installed\\. Selected extras: (.+?)","errorType":"exception","errorClass":"ExtraNotInstalledError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/update_check.py","lineNumber":3801,"sourceCode":"            f\"Invalid extra name {extra!r}: must match PEP 508 \"\n            f\"({_EXTRA_NAME_RE.pattern})\"\n        )\n        raise ValueError(msg)\n    from deepagents_code.extras_info import BASE_DEPENDENCY_EXTRAS\n\n    selected_extra = canonicalize_name(extra)\n    if selected_extra in BASE_DEPENDENCY_EXTRAS:\n        msg = f\"Extra {extra!r} is a base dependency and cannot be removed.\"\n        raise ProtectedExtraError(msg)\n\n    extras = _uv_tool_selected_extras(distribution_name=distribution_name)\n    conflict = _composite_extra_conflict_message(extra, selected=extras)\n    if conflict is not None:\n        raise CompositeExtraConflictError(conflict)\n    if selected_extra not in extras:\n        listed = \", \".join(sorted(extras)) or \"(none)\"\n        msg = f\"Extra {extra!r} is not installed. Selected extras: {listed}\"\n        raise ExtraNotInstalledError(msg)\n    return _uv_tool_install_command(\n        version=version,\n        include_prereleases=_resolve_include_prereleases(\n            None, installed=_parse_version(version)\n        ),\n        distribution_name=distribution_name,\n        extras_to_remove=(selected_extra,),\n        reinstall=True,\n    )\n\n\ndef _composite_extra_conflict_message(\n    extra: str,\n    *,\n    selected: Collection[str],\n) -> str | None:\n    \"\"\"Return why a selected composite prevents removing `extra`, if any.\n","sourceCodeStart":3783,"sourceCodeEnd":3819,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/update_check.py#L3783-L3819","documentation":"Raised when the extra to remove is not among the currently selected/installed uv tool extras. The library checks membership in the selected set after canonicalizing the name and reports the full list of what is installed to help correct the input.","triggerScenarios":"Calling the remove-extra API (update_check.py) with an extra whose canonicalized name is absent from the set returned by _uv_tool_selected_extras; also when no extras are installed at all (message shows '(none)').","commonSituations":"Typo in the extra name or wrong casing; the extra was already removed; assuming an extra exists when the tool was installed without it; switching between distributions/versions with different extra sets.","solutions":["Check the selected extras listed in the message and use an exact installed name.","Install the extra first if you actually intended to add it, not remove it.","Canonicalize/normalize the extra name (underscores/hyphens/case) before calling."],"exampleFix":"// before\nremove_extra('browser_tool')  # not installed\n// after\nremove_extra('browser-tools')","handlingStrategy":"validation","validationCode":"from deepagents_code.update_check import _uv_tool_selected_extras\nfrom packaging.utils import canonicalize_name\nselected = {canonicalize_name(e) for e in _uv_tool_selected_extras(distribution_name=dist)}\nif canonicalize_name(name) not in selected:\n    raise KeyError(f'{name} is not installed; selected: {sorted(selected)}')","typeGuard":null,"tryCatchPattern":"try:\n    remove_extra(name)\nexcept ExtraNotInstalledError as e:\n    logger.info('nothing to do: %s', e)  # idempotent removal","preventionTips":["Canonicalize extra names (hyphen/underscore/case) before comparing","Treat removal of a non-installed extra as a no-op for idempotent scripts","Install the extra first if removal was a mistake"],"tags":["extras","validation","not-installed"],"backgroundTag":"extra-not-installed","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}