Skip to content

feat: add atomic write utilities for safe file operations#5500

Merged
ruben-arts merged 2 commits intoprefix-dev:mainfrom
baszalmstra:claude/temp-file-pixi-toml-8lWI7
Mar 3, 2026
Merged

feat: add atomic write utilities for safe file operations#5500
ruben-arts merged 2 commits intoprefix-dev:mainfrom
baszalmstra:claude/temp-file-pixi-toml-8lWI7

Conversation

@baszalmstra
Copy link
Contributor

Description

This PR introduces atomic write utilities to ensure safe file operations across the codebase. The changes add two new functions (atomic_write and atomic_write_sync) that write to a temporary file in the same directory and then atomically rename it to the target path. This prevents partial writes and ensures data integrity if operations fail (e.g., due to disk full).

The implementation uses tempfile::NamedTempFile to create temporary files in the same directory as the target, ensuring they're on the same filesystem for atomic rename operations. If the write fails, the temporary file is automatically cleaned up.

Fixes #5463

How Has This Been Tested?

The changes replace existing file write operations with atomic variants. Existing tests that cover manifest saving and workspace operations will validate the new implementation. The atomic write functions maintain the same error handling semantics as the previous fs_err calls, ensuring compatibility with existing error handling paths.

AI Disclosure

Written by Claude Code Opus 4.6 Extended.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas

Write manifest files (pixi.toml, pyproject.toml, global manifest) via a
temporary file in the same directory followed by an atomic rename. This
prevents data loss when a write fails mid-operation (e.g. due to a full
disk), since the original file remains untouched until the new content
is fully written.

Adds `pixi_utils::atomic_write` module with both async and sync
variants, and updates all manifest write sites:
- WorkspaceMut::save_inner() (async)
- WorkspaceMut::revert() (async)
- WorkspaceMut::Drop::drop() (sync)
- pixi_global Manifest::save() (async)

Closes prefix-dev#5463

https://claude.ai/code/session_019JHCPv8zTSRHkm5teuTyp6
@baszalmstra baszalmstra force-pushed the claude/temp-file-pixi-toml-8lWI7 branch from 180d92c to 477292a Compare February 13, 2026 13:08
Copy link
Contributor

@ruben-arts ruben-arts left a comment

Choose a reason for hiding this comment

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

Changes make sense, I don't have the time to test it on a temp filesystem. But it doesn't break existing workflows so I'll approve it without validating that this solves the problem described in issue #5463. Let's see if the issue comes back.

@ruben-arts ruben-arts merged commit fb26e74 into prefix-dev:main Mar 3, 2026
37 checks passed
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.

No space left on device (os error 28) causes pixi.toml content loss

3 participants