--dry-run is accepted as a global flag on every subcommand, but only some command modules act on it. On the rest it parses cleanly, prints a result that looks like a preview, and performs the mutation anyway.
I hit this on relations add:
$ linear-cli relations add --relation blocked-by ENG-843 ENG-899 --dry-run -o json
{
"issueRelation": {
"id": "bfd68e80-...",
"issue": { "identifier": "ENG-899" },
"relatedIssue": { "identifier": "ENG-843" },
"type": "blocks"
},
"success": true
}
The relation was real. Querying it back gave a createdAt matching the moment I ran the command, and I had to relations remove it. Nothing in the output distinguishes this from a genuine preview — "success": true and a populated id read as confirmation either way.
grep -rl dry_run src/commands/ shows which modules handle it:
Handles it: milestones roadmaps documents import issues sync views webhooks projects statuses initiatives templates cycles
Contains mutations but never reads dry_run: relations bulk comments labels attachments teams time triage project_updates favorites notifications sprint api interactive
bulk is the one I would prioritize — it is the command where a user is most likely to reach for --dry-run first, and it is the one where being wrong is most expensive.
Two options, either of which closes the trap:
- Implement
--dry-run in the remaining modules.
- Cheaper and safer in the meantime: reject
--dry-run with a clear error on any command that does not implement it. A loud "not supported for this command" is strictly better than a silent mutation, and it makes the gap self-documenting.
Happy to send a PR for (2) if you would like it — it is a small change and it stops the bleeding while (1) gets filled in per module.
Reported from an agent harness where --dry-run is exactly the guard we lean on before letting automation touch a workspace.
--dry-runis accepted as a global flag on every subcommand, but only some command modules act on it. On the rest it parses cleanly, prints a result that looks like a preview, and performs the mutation anyway.I hit this on
relations add:The relation was real. Querying it back gave a
createdAtmatching the moment I ran the command, and I had torelations removeit. Nothing in the output distinguishes this from a genuine preview —"success": trueand a populated id read as confirmation either way.grep -rl dry_run src/commands/shows which modules handle it:Handles it:
milestonesroadmapsdocumentsimportissuessyncviewswebhooksprojectsstatusesinitiativestemplatescyclesContains mutations but never reads
dry_run:relationsbulkcommentslabelsattachmentsteamstimetriageproject_updatesfavoritesnotificationssprintapiinteractivebulkis the one I would prioritize — it is the command where a user is most likely to reach for--dry-runfirst, and it is the one where being wrong is most expensive.Two options, either of which closes the trap:
--dry-runin the remaining modules.--dry-runwith a clear error on any command that does not implement it. A loud "not supported for this command" is strictly better than a silent mutation, and it makes the gap self-documenting.Happy to send a PR for (2) if you would like it — it is a small change and it stops the bleeding while (1) gets filled in per module.
Reported from an agent harness where
--dry-runis exactly the guard we lean on before letting automation touch a workspace.