Relationships
#3011 readModelData silently drops data written before a model instance rename
Opened by dmc · 10/5/2026· Shipped 10/5/2026
Description
context.readModelData(modelName, specName) returns only records whose stored
modelName tag equals the name passed. That tag is stamped when a record is
written, and it is not updated when the model instance is renamed. After a
rename (editing the definition's name; the model ID does not change), every
record written before the rename is silently excluded — although the data still
belongs to the same model ID, and swamp data list <new-name> shows it.
The two code paths in DataAccessService.readModelData
(src/domain/data/data_access_service.ts) disagree:
- Catalog path (
dataQueryServicepresent — the normal case): queries the tags withmodelName == "<name>" && specName == "<spec>". Pre-rename records are excluded. - Fallback path (no catalog): resolves the name to the model ID and reads everything under it (plus orphan recovery for previous IDs). Pre-rename records are included.
So the same call returns different data depending on an internal detail.
Steps to reproduce
- Create a model instance
old-nameand run a method that writes a resource of specfoo. - Rename the instance: edit the definition YAML
name: old-name→name: new-name(sameid).swamp model validate new-namepasses. - Run a method again so it writes another
foorecord (now taggedmodelName: new-name). - In a method of
new-name, callcontext.readModelData([HOST-1], "foo").
Expected: both foo records (same model ID).
Actual: only the record written after the rename.
swamp data list new-name lists both, and
swamp data get new-name <older-record> --json shows
tags.modelName: "old-name".
Impact
Silent data loss from the method's point of view. In our case, an extension's snapshot/image retention records that were written before a rename became invisible to its prune and rollback methods, so those snapshots would never have been pruned. Nothing errors or warns.
Suggested fix (high level)
Make the catalog path resolve the name to the model ID and match on the model
ID (with the same orphan-recovery scope as the fallback path), or update the
modelName tag on existing data when a definition is renamed. At minimum,
document that readModelData matches the name recorded at write time.
Workaround: read a model's own data by ID with
context.dataRepository.findAllForModel(context.modelType, context.modelId).
Environment
- swamp 20261003.192630.0-sha.bed0772a (latest; the catalog-path query is unchanged from 20260904.171927.0)
- macOS, filesystem datastore with the data catalog present
Shipped
Click a lifecycle step above to view its details.
dmc commented 10/5/2026, 2:41:00 AM
Correction to step 4: the automatic redaction replaced code with [HOST-1]. It is not a hostname. The first argument is the calling model's own definition name (the name field of context -> definition). So step 4 is: in a method of new-name, call readModelData with the model's own name and spec "foo".
stack72 commented 10/5/2026, 3:22:00 PM
Thanks @dmc for reporting this! We shipped: Make context.readModelData include data written before a model instance rename. Keep today's name-tag query and add an indexed query on the definition identity (type and id), merged and de-duplicated, on both the in-process catalog path and the remote-worker path. A model reading its own name uses its own identity with no lookup; other names are resolved through the definition repository. modelType/modelId literal equalities are pushed down to SQL. Strict superset of today's results, benchmarked against the released binary.. The fix has been merged and a release is on its way. We appreciate your contribution to swamp.
Sign in to post a ripple.