{"record":{"id":"93e4a995d07ca7a7","repo":"langchain-ai/deepagents","slug":"name-symlink-entries-are-not-supported","errorCode":null,"errorMessage":"{name}: symlink entries are not supported","messagePattern":"(.+?): symlink entries are not supported","errorType":"error_code","errorClass":"FleetImportError","httpStatus":null,"severity":"error","filePath":"libs/talon/deepagents_talon/fleet_import.py","lineNumber":225,"sourceCode":"def _validated_entries(archive: zipfile.ZipFile) -> dict[str, zipfile.ZipInfo]:\n    entries: dict[str, zipfile.ZipInfo] = {}\n    total_size = 0\n    for info in archive.infolist():\n        name = _normalized_zip_name(info.filename)\n        if name is None:\n            continue\n        if _is_unsafe_zip_path(name):\n            msg = f\"{info.filename}: unsafe zip path\"\n            raise FleetImportError(msg)\n        if _is_symlink(info):\n            msg = f\"{name}: symlink entries are not supported\"\n            raise FleetImportError(msg)\n        if info.is_dir():\n            continue\n        _validate_zip_entry_size(name, info)\n        if len(entries) >= _MAX_ZIP_ENTRY_COUNT:\n            msg = f\"{archive.filename}: too many zip entries\"\n            raise FleetImportError(msg)\n        total_size += info.file_size\n        if total_size > _MAX_ZIP_UNCOMPRESSED_BYTES:\n            msg = f\"{archive.filename}: zip uncompressed size exceeds limit\"\n            raise FleetImportError(msg)\n        entries[name] = info\n    return entries\n\n\ndef _normalized_zip_name(name: str) -> str | None:\n    normalized = name.replace(\"\\\\\", \"/\")\n    if not normalized or normalized.endswith(\"/\"):\n        return None\n    return normalized\n\n\ndef _is_unsafe_zip_path(name: str) -> bool:\n    posix = PurePosixPath(name)\n    windows = PureWindowsPath(name)","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/talon/deepagents_talon/fleet_import.py#L207-L243","documentation":"The library rejects zip entries that are symlinks (external-attr Unix file type `S_IFLNK`). Extracting symlinks from untrusted archives enables link attacks, so Fleet import refuses them outright. The normalized entry name is in the message.","triggerScenarios":"`import_fleet_zip` encounters an entry whose `ZipInfo.external_attr >> 16` masked with `0o170000` equals `0o120000`, i.e. a symlink stored with Unix attributes.","commonSituations":"Archives created with `zip -y` or tar-like tooling that preserves symlinks (e.g. `node_modules/.bin/*` symlinks, docs links), macOS `ditto`/Finder zips containing aliases, or reproducible-build pipelines using symlinked files.","solutions":["Find the symlink entries (`zi.external_attr >> 16 == 0o120000`) and replace them with real file copies in the export","Recreate the archive without symlink preservation (plain `zip -r` or Python `zipfile` writes)","Check your build/export pipeline flags that keep symlinks (`-y`, `--dereference` differences) and disable them"],"exampleFix":"# before (keeps symlinks)\nzip -ry fleet.zip AGENTS.md skills\n// after\nzip -r fleet.zip AGENTS.md skills  # symlinks stored as regular copies or omitted","handlingStrategy":"validation","validationCode":"import zipfile\n\ndef has_symlink_entries(path):\n    with zipfile.ZipFile(path) as z:\n        return any(\n            (zi.external_attr >> 16) & 0o170000 == 0o120000\n            for zi in z.infolist()\n        )","typeGuard":"def is_symlink_entry(info: zipfile.ZipInfo) -> bool:\n    return ((info.external_attr >> 16) & 0o170000) == 0o120000","tryCatchPattern":"try:\n    import_fleet_zip(zip_path, target_dir=target)\nexcept FleetImportError as exc:\n    if \"symlink entries are not supported\" in str(exc):\n        print(f\"Rebuild archive without symlink: {exc}\")\n    raise","preventionTips":["Create export zips without symlink preservation (avoid `zip -y`)","Replace symlinks with real file copies before zipping","Scan for symlink entries (external_attr file type) before importing"],"tags":["security","zip","symlink","validation"],"backgroundTag":"zip-symlink-entry-rejected","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}