rivet modify --set-field replaces the header line of a block scalar (> / |) but leaves the indented continuation lines behind. The result is unparseable YAML, and modify prints modified <ID> as if it succeeded. The next rivet validate fails on a file the tool itself just wrote.
rivet 0.32.0 (ec436b8 HEAD 2026-08-05), on pulseengine/meld.
Reproduction
SR-32 in safety/requirements/safety-requirements.yaml has a block-scalar field:
verification-description: >
Foundation: stackful_intrinsic_signatures_pinned +
stackful_lift_is_async_without_callback. Emitter:
sr32_has_callback_export_detects_companion (detection),
...
$ rivet validate | tail -1
Result: PASS (105 warnings)
$ rivet modify SR-32 --set-field "verification-description=SHORT TEST VALUE"
modified SR-32
$ rivet validate | tail -1
Result: FAIL (8 errors, 105 warnings, 0 broken cross-refs)
The file now reads:
verification-description: SHORT TEST VALUE
Foundation: stackful_intrinsic_signatures_pinned +
stackful_lift_is_async_without_callback. Emitter:
...
The > header was replaced by the new scalar; its body was not removed. Errors reported are expected ':' after mapping key at each orphaned line.
Why it matters
The project instruction in this repo is to mutate artifacts only through the rivet CLI, never by hand-editing artifact YAML. This makes that impossible for any field stored as a block scalar, which is most long prose fields (verification-description, fix, scenario). The workaround is exactly what the rule forbids: hand-edit the YAML.
Worse than the corruption is the exit status: modify returns 0 and prints modified SR-32. A script that edits several artifacts and checks exit codes will keep going over a corrupted file. I hit this while correcting stale test citations (meld#411) and only noticed because I ran rivet validate afterwards.
--set-description on the same run did not corrupt sw-verifications.yaml, so this looks specific to --set-field (or to how that file's fields are emitted).
Suggested
- Replace the whole field node, not the header line — or re-emit the artifact through the YAML writer instead of patching text.
- Until that lands,
modify should at minimum re-parse the file it wrote and fail loudly (non-zero) rather than reporting success.
Happy to test a fix against meld's record, which has plenty of block-scalar fields.
rivet modify --set-fieldreplaces the header line of a block scalar (>/|) but leaves the indented continuation lines behind. The result is unparseable YAML, andmodifyprintsmodified <ID>as if it succeeded. The nextrivet validatefails on a file the tool itself just wrote.rivet 0.32.0 (ec436b8 HEAD 2026-08-05), on pulseengine/meld.
Reproduction
SR-32insafety/requirements/safety-requirements.yamlhas a block-scalar field:The file now reads:
The
>header was replaced by the new scalar; its body was not removed. Errors reported areexpected ':' after mapping keyat each orphaned line.Why it matters
The project instruction in this repo is to mutate artifacts only through the rivet CLI, never by hand-editing artifact YAML. This makes that impossible for any field stored as a block scalar, which is most long prose fields (
verification-description,fix,scenario). The workaround is exactly what the rule forbids: hand-edit the YAML.Worse than the corruption is the exit status:
modifyreturns 0 and printsmodified SR-32. A script that edits several artifacts and checks exit codes will keep going over a corrupted file. I hit this while correcting stale test citations (meld#411) and only noticed because I ranrivet validateafterwards.--set-descriptionon the same run did not corruptsw-verifications.yaml, so this looks specific to--set-field(or to how that file's fields are emitted).Suggested
modifyshould at minimum re-parse the file it wrote and fail loudly (non-zero) rather than reporting success.Happy to test a fix against meld's record, which has plenty of block-scalar fields.