langchain-ai/deepagents · error · FleetImportError
{path}: unsafe subagent name {name!r}
Error message
{path}: unsafe subagent name {name!r} What it means
A subagent directory name taken from `subagents/<name>/AGENTS.md` or `subagents/<name>/tools.json` fails validation: it must fully match `[A-Za-z0-9_.-]{1,128}` and not be `.` or `..`. Names outside this set could escape the `agents/` directory or produce unusable paths, so import aborts with the offending path in the message.
Source
Thrown at libs/talon/deepagents_talon/fleet_import.py:306
def _copy_zip_file(archive: zipfile.ZipFile, info: zipfile.ZipInfo, target: Path) -> None:
target.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
copied = 0
with archive.open(info) as src, target.open("wb") as dst:
while chunk := src.read(_COPY_CHUNK_SIZE):
copied += len(chunk)
if copied > info.file_size or copied > _MAX_ZIP_UNCOMPRESSED_BYTES:
msg = f"{info.filename}: zip entry expanded beyond declared size"
raise FleetImportError(msg)
dst.write(chunk)
target.chmod(0o600)
def _validate_agent_name(name: str, path: str) -> None:
if not _AGENT_ID_PATTERN.fullmatch(name) or name in {".", ".."}:
msg = f"{path}: unsafe subagent name {name!r}"
raise FleetImportError(msg)
def _is_subagent_prompt_path(name: str) -> bool:
parts = PurePosixPath(name).parts
return (
len(parts) == _SUBAGENT_FILE_PARTS and parts[0] == "subagents" and parts[2] == "AGENTS.md"
)
def _is_subagent_tools_path(name: str) -> bool:
parts = PurePosixPath(name).parts
return (
len(parts) == _SUBAGENT_FILE_PARTS and parts[0] == "subagents" and parts[2] == "tools.json"
)
def _mcp_summaries(staging: Path, source: Path) -> list[_ServerSummary]:
grouped: dict[tuple[str, str], _ServerSummary] = {}View on GitHub (pinned to a1af029e6e)
Solutions
- Rename the subagent directory in the export to only `[A-Za-z0-9_.-]`, max 128 chars (e.g. `my-assistant`)
- Pre-check names before zipping: regex-fullmatch every `subagents/*/` folder name
- Check the path in the error message to identify which folder to rename; update any cross-references to the old name
Example fix
// before subagents/My Assistant!/AGENTS.md // after subagents/my-assistant/AGENTS.md
Defensive patterns
Strategy: validation
Validate before calling
import re
import zipfile
PATTERN = re.compile(r"[A-Za-z0-9_.-]{1,128}")
def has_unsafe_agent_names(path):
with zipfile.ZipFile(path) as z:
for name in z.namelist():
parts = name.replace("\\", "/").split("/")
if len(parts) == 3 and parts[0] == "subagents":
if not PATTERN.fullmatch(parts[1]) or parts[1] in {".", ".."}:
return True
return False Type guard
def is_safe_agent_name(name: str) -> bool:
return bool(re.fullmatch(r"[A-Za-z0-9_.-]{1,128}", name)) and name not in {".", ".."} Try / catch
try:
import_fleet_zip(zip_path, target_dir=target)
except FleetImportError as exc:
if "unsafe subagent name" in str(exc):
print(f"Rename subagent dir to [A-Za-z0-9_.-] only: {exc}")
raise Prevention
- Name subagent folders with kebab-case ASCII identifiers
- Validate folder names in your export pipeline before zipping
- Avoid spaces, unicode, and punctuation in agent directory names
When it happens
Trigger: `import_fleet_zip` materializes a subagent file whose second path component contains characters like spaces, slashes, unicode, `~`, `!`, `@`, `#`, or is longer than 128 chars, or equals `.`/`..`.
Common situations: Fleet exports where subagent folders were named with human-friendly labels (`My Assistant!`), localization characters (`Assistanté`), or copy-paste artifacts (trailing spaces).
Related errors
- Invalid agent name: {agent_name!r} is reserved for dcode's o
- temporary artifact provenance is invalid
- trusted_ask_user_tool must be named ask_user
- trusted_compaction_tool must be named compact_conversation
- Invalid server name {server_name!r}: server names must conta
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/09750fd53c74c48f.
Report an issue: GitHub.