Skip to content

fix: SFTP upload auto-creates remote dirs; fix recursive upload and mkdir v4+#114

Merged
Orinks merged 2 commits intodevfrom
fix/portkeydrop-bug-hunt
Mar 22, 2026
Merged

fix: SFTP upload auto-creates remote dirs; fix recursive upload and mkdir v4+#114
Orinks merged 2 commits intodevfrom
fix/portkeydrop-bug-hunt

Conversation

@Orinks
Copy link
Owner

@Orinks Orinks commented Mar 22, 2026

Summary

  • SFTP upload SFTPNoSuchFile: SFTPClient.upload now catches FileNotFoundError from both the native put() path and the BytesIO fallback. On first failure it calls sftp.makedirs(parent, exist_ok=True) and retries — so uploading to a remote directory that doesn't exist yet no longer crashes.

  • Recursive upload bug: _run_recursive_upload never created the top-level destination folder itself (only subdirs). Seeding dirs_to_create with job.destination fixes this. Sorted order guarantees parents are always created before children.

  • SFTP mkdir verification (v4+ servers): SFTPClient.mkdir post-create verification now checks the SFTP v4+ type attribute in addition to permissions, consistent with stat() and chdir(). Servers that return type=2 (directory) but omit permission bits would previously raise a spurious RuntimeError after a successful mkdir.

Test plan

  • tests/test_protocols.py — new tests for upload auto-creates remote dir (native and BytesIO paths), and mkdir succeeds when type indicates directory without permissions
  • tests/test_transfer_service.py — new tests for recursive upload creates top-level and nested dirs in order
  • Full suite: 782 passed, 0 failed

🤖 Generated with Claude Code

Orinks and others added 2 commits March 22, 2026 13:58
…type check

- SFTPClient.upload now catches FileNotFoundError from both the native
  put() path and the BytesIO fallback path; on failure it calls
  sftp.makedirs(parent, exist_ok=True) and retries, so uploading to a
  path like '/audiobooks/01 - Harry Potter...' no longer raises
  SFTPNoSuchFile when the remote directory does not yet exist.

- SFTPClient.mkdir verification now checks the SFTP v4+ `type`
  attribute in addition to `permissions`, matching the same pattern used
  by stat() and chdir().  Servers that return type=2 (directory) but
  omit permission bits would previously raise a spurious RuntimeError
  after a successful mkdir.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ectory

_run_recursive_upload collected only subdirectories into dirs_to_create,
stopping the walk when remote_parent == job.destination.  The top-level
destination folder itself was never created, so mkdir calls for its
children would fail and subsequent file uploads would error out.

Fix: seed dirs_to_create with job.destination so it is always created
first (sorted order guarantees parent dirs precede their children).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Orinks Orinks merged commit 4a38f72 into dev Mar 22, 2026
6 checks passed
@Orinks Orinks deleted the fix/portkeydrop-bug-hunt branch March 22, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant