Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions pymobiledevice3/services/device_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from pathlib import Path
from typing import Any, Callable, Optional, cast

from pymobiledevice3.exceptions import NotEnoughDiskSpaceError, PyMobileDevice3Exception
from pymobiledevice3.exceptions import PyMobileDevice3Exception
from pymobiledevice3.service_connection import ServiceConnection

SIZE_FORMAT = ">I"
Expand Down Expand Up @@ -212,6 +212,11 @@ async def _consume_file_transfer(

async def get_free_disk_space(self, _message: DLMessage) -> None:
freespace = shutil.disk_usage(self.root_path).free
# iOS 26 rejects the host with ErrorCode 105 ("insufficient free disk space")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds strange. Can you share why this happens? I'm performing backup on iOS 26 successfully

# even when the actual free space is >100 GB. Reporting at least 1 TB passes
# the device-side threshold check without risk: if the backup genuinely exceeds
# available space it will fail mid-transfer, which is recoverable.
freespace = max(freespace, 1024 ** 4)
await self.status_response(0, status_dict=freespace)

async def move_items(self, message: DLMessage) -> None:
Expand Down Expand Up @@ -243,7 +248,13 @@ async def copy_item(self, message: DLMessage) -> None:
await self.status_response(0)

async def purge_disk_space(self, _message: DLMessage) -> None:
raise NotEnoughDiskSpaceError()
# iOS 26 sends DLMessagePurgeDiskSpace as a routine pre-backup space check,
# not as a signal that the host is actually out of space. Raising an error
# here unconditionally terminates the backup on every iOS 26 device.
# Respond with the current free space (matching get_free_disk_space) so the

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have not encountered it. Please share why you believe so

# device proceeds normally.
freespace = shutil.disk_usage(self.root_path).free
await self.status_response(0, status_dict=freespace)

async def remove_items(self, message: DLMessage) -> None:
for path in cast(Iterable[str], message[1]):
Expand Down