Relationships
#3955 Filesystem datastore: an unclean shutdown leaves zero-byte data versions as the latest version, and `doctor datastores --repair` does not detect them
Opened by anthony · 10/26/2026
Description
The filesystem datastore does not write data versions atomically. An unclean shutdown during a write leaves the version directory with an empty raw file and an empty metadata.yaml file. The latest pointer file and the catalog row (is_latest = 1) already point to the empty version.
After this:
swamp data queryreturns the record withcontent: {}. CEL that reads a field fails, for exampleNo such key: stageId. Every workflow that queries the spec fails.swamp data get <model> <name>returnsnot_found.swamp data versionsdoes not list the empty versions, but the catalog keeps them.swamp doctor datastoresreportspass.--repairreports "Catalog index matches data on disk". The check only compares disk to catalog. It does not check for empty content, and it does not check for catalog rows whose files have no content.
No CLI command can recover the record. swamp data delete removes all versions of a record, not one version. No command rebuilds the catalog from disk.
Observed impact
One unclean shutdown made 168 files zero bytes. All files had the same mtime. 26 records had an empty latest version. These records included the state, journal, status and evidence records of three active @swamp/software-factory work items. The work items stopped for two days with no error until a workflow evaluated a field of the empty record.
The @swamp/workflow-summary report for the run that wrote the empty version shows succeeded.
Steps to reproduce
- Run a method that writes a new version of a resource. Stop the VM or host before the OS flushes the file data to disk, for example
wsl --shutdownon WSL2. (This step is not verified. The observed failure came from an unplanned stop at an unknown point in the write.) - Run
swamp data query '<predicate that matches the record>' --json. Result:content: {}. - Run
swamp data get <model> <name>. Result:not_found. - Run
swamp doctor datastores --repair. Result: no findings.
Manual recovery that worked
- Move the empty version directories out of the record directory.
- Write the last good version number into the
latestfile. - In
.swamp/data/_catalog.db, delete the rows for the moved versions. Setis_latest = 1on the last good version. For each (workflow, job, step) group that lost itsis_step_latestrow, setis_step_latest = 1on the highest remaining version of the group.
Suggested changes
- Write
rawandmetadata.yamlto a temporary file, call fsync, then rename. Updatelatestand the catalog only after the rename. - Make
swamp doctor datastoresfind versions with zero-byte or unparseable content, and catalog rows that have no readable content on disk. - Make
--repairroll a record back to its last readable version and correctis_latestandis_step_latestin the catalog.
Environment
- swamp 20261022.021804.0-sha.983e2929
- Linux 6.18.33.2-microsoft-standard-WSL2 (WSL2), filesystem datastore
- Writes came from
swamp servescheduled workflows
Open
No activity in this phase yet.
Sign in to post a ripple.