[Bug]: Failed startup loads can delete bundles and publish unusable state
- Dominant language
- Swift
- Stars
- 49.9k
- Forks
- 1.8k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 22
Description
### I have done the following
- [x] I have searched the existing issues
- [x] I have reproduced the issue using the `main` branch of this project
### Steps to reproduce
During testing of my Container Compose plugin, I found two related startup persistence failures on stock `apple/container` `main` at `48145ac7fb177d9fb14e015a0bdea4c642b36729`.
#### Unloadable metadata
1. Create a directory under the container bundle root.
2. Put malformed JSON in both `config.json` and the legacy fallback `runtime-configuration.json`.
3. Call `ContainersService.loadAtBoot`.
4. Observe that the entire bundle directory is deleted by the catch block.
#### Missing runtime plugin
1. Create a valid container bundle whose configuration names a runtime plugin that is not currently registered.
2. Call `ContainersService.loadAtBoot`.
3. Observe that a stopped `ContainerState` is inserted before runtime availability is checked.
4. The subsequent error is caught and the bundle is deleted, but the unusable in-memory state remains in the returned dictionary.
The same bundle writer persists JSON directly to `config.json`, `options.json`, `kernel.json`, and `rootfs.json`. A process interruption during one of these writes can therefore leave truncated metadata that triggers the destructive startup path.
### Problem description
`ContainersService.loadAtBoot` deletes a user's complete on-disk container bundle for every load error, including transient runtime-plugin availability and recoverable metadata errors. In the missing-runtime case, it also returns an in-memory state for the bundle it just deleted because state insertion happens before validation.
Startup should preserve unloadable bundles for diagnosis or a later successful load, reject them from the returned in-memory state, and log the failure. Bundle metadata replacements should be atomic so an interrupted write cannot expose partially written JSON.
### Environment
- OS: macOS 26.5.1 (25F80)
- Xcode: 26.6 (17F113)
- Swift: 6.3.3
- Container: source `main` at `48145ac7fb177d9fb14e015a0bdea4c642b36729`
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Contributor guide
Research direction
Start at ContainersService.loadAtBoot and trace the bundle writer that persists config.json, options.json, kernel.json, and rootfs.json. Reproduce malformed metadata and a missing runtime plugin; done means unloadable bundles are preserved, rejected from returned state, failures are logged, and interrupted metadata writes cannot expose partial JSON.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100