langchain-ai/deepagents · error · ProtectedExtraError
Extra {extra!r} is a base dependency and cannot be removed.
Error message
Extra {extra!r} is a base dependency and cannot be removed. What it means
Raised when the requested extra is one of the BASE_DEPENDENCY_EXTRAS shipped with the tool by default. Base extras are integral to the distribution and cannot be removed independently. The check compares the canonicalized name against the protected set before consulting installed extras.
Source
Thrown at libs/code/deepagents_code/update_check.py:3792
CompositeExtraConflictError: If a selected composite supplies `extra`.
ExtraNotInstalledError: If `extra` is not selected in this install.
Propagates `ToolRequirementIntrospectionError` if the uv tool receipt cannot
be read, or does not safely describe the selected extras, the interpreter, or
the `--with` packages.
"""
if not is_valid_extra_name(extra):
msg = (
f"Invalid extra name {extra!r}: must match PEP 508 "
f"({_EXTRA_NAME_RE.pattern})"
)
raise ValueError(msg)
from deepagents_code.extras_info import BASE_DEPENDENCY_EXTRAS
selected_extra = canonicalize_name(extra)
if selected_extra in BASE_DEPENDENCY_EXTRAS:
msg = f"Extra {extra!r} is a base dependency and cannot be removed."
raise ProtectedExtraError(msg)
extras = _uv_tool_selected_extras(distribution_name=distribution_name)
conflict = _composite_extra_conflict_message(extra, selected=extras)
if conflict is not None:
raise CompositeExtraConflictError(conflict)
if selected_extra not in extras:
listed = ", ".join(sorted(extras)) or "(none)"
msg = f"Extra {extra!r} is not installed. Selected extras: {listed}"
raise ExtraNotInstalledError(msg)
return _uv_tool_install_command(
version=version,
include_prereleases=_resolve_include_prereleases(
None, installed=_parse_version(version)
),
distribution_name=distribution_name,
extras_to_remove=(selected_extra,),
reinstall=True,
)View on GitHub (pinned to a1af029e6e)
Solutions
- Remove only genuinely optional extras; check BASE_DEPENDENCY_EXTRAS (deepagents_code.extras_info) to see which names are protected.
- If the goal is a minimal install, reinstall the tool without extras rather than removing base ones.
- If you really need different base dependencies, use a different distribution or install method instead of the tool-extras flow.
Example fix
// before
remove_extra('core') # base dependency
// after
remove_extra('search-tools') # optional extra Defensive patterns
Strategy: validation
Validate before calling
from deepagents_code.extras_info import BASE_DEPENDENCY_EXTRAS
from packaging.utils import canonicalize_name
if canonicalize_name(name) in BASE_DEPENDENCY_EXTRAS:
raise ValueError(f'{name} is a base dependency and cannot be removed') Try / catch
try:
remove_extra(name)
except ProtectedExtraError as e:
logger.warning('skipping protected extra: %s', e) Prevention
- Consult BASE_DEPENDENCY_EXTRAS before removing any extra
- Filter base extras out of bulk-removal scripts
- Prefer reinstalling without extras over trying to remove base ones
When it happens
Trigger: Calling the remove-extra API (update_check.py) with an extra whose canonical name is in BASE_DEPENDENCY_EXTRAS, e.g. attempting to remove a core bundled extra by any casing/normalization variant.
Common situations: Trying to slim down the installation by removing what looks like an optional extra but is actually a base dependency; scripting bulk removal of all extras including base ones.
Related errors
- uv tool receipt contains invalid extras on the tool requirem
- uv tool receipt contains duplicate canonical extra names
- Extra {extra!r} is not installed. Selected extras: {listed}
- modes can only be provided when agent is a factory
- models can only be provided when agent is a factory
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/7bc507802206ba46.
Report an issue: GitHub.