Skip to content

update-many --dry-run skips field validation (priority/type/status/deadline), producing false-positive plans that fail on apply #256

Closed

Description

@unbraind

Summary

pm update-many --dry-run does not validate field values (--priority, --type, --status, --deadline), so it produces a false-positive plan that looks valid but fails when the identical command is actually applied. The dry-run contract ("preview exactly what will happen") is broken for invalid inputs.

By contrast, single-item pm update and pm create do validate these fields immediately, and update-many apply mode also validates. Only update-many --dry-run skips validation.

Reproduce (extension-free, clean tracker)

pm init --pm-path /tmp/repro
pm --no-extensions --pm-path /tmp/repro create --type Task --title "t1"

# 1. Dry-run with INVALID priority (valid range is 0-4): NO error, shows planned change
pm --no-extensions --pm-path /tmp/repro update-many --filter-type Task --priority 99 --dry-run
# => mode: dry_run
#    item_plans: [{ changes: [{ field: priority, before: 2, after: 99 }] }]
#    (no error)

# 2. Apply the SAME command: rejects it
pm --no-extensions --pm-path /tmp/repro update-many --filter-type Task --priority 99
# => error: "Invalid priority \"99\". Accepted values: numbers 0..4 ..."

The same gap exists for other validated fields — dry-run accepts them all, apply rejects:

pm --no-extensions --pm-path /tmp/repro update-many --filter-type Task --type BogusType --dry-run       # dry-run: after: "BogusType", no error
pm --no-extensions --pm-path /tmp/repro update-many --filter-type Task --status BogusStatus --dry-run  # dry-run: after: "BogusStatus", no error
pm --no-extensions --pm-path /tmp/repro update-many --filter-type Task --deadline "not-a-date" --dry-run # dry-run: after: "not-a-date", no error

The JSON dry-run output is also affected (--dry-run --json): item_plans contain no errors for invalid values.

Expected

--dry-run should validate field values identically to apply mode, so the preview accurately reflects whether the apply will succeed. Invalid values should surface as errors/warnings in the dry-run output (per-item or up-front), matching what apply will reject.

Actual

--dry-run accepts any value without validation and presents invalid values (priority 99, type BogusType, status BogusStatus, deadline not-a-date) as valid planned changes with no error. The user trusts the dry-run, runs apply, and discovers the failure only then.

Additionally, dry-run does not normalize names to numbers: --priority critical shows after: "critical" (string) rather than the normalized 0 that apply would store.

Environment

  • pm version: 2026.6.13
  • Reproduced with --no-extensions in a clean throwaway tracker (no custom extensions involved).

Activity

  1. unbraind commented on Jul 11, 2026

    @unbraind
    OwnerAuthor

    pm tracker item:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions