Troubleshooting pm-cli

Agent Quick Context

  • Storage: .agents/pm/ โ€” TOON format by default, JSON markdown also supported
  • Config: .agents/pm/settings.json
  • History: .agents/pm/history/<id>.jsonl (append-only, never edit directly)
  • Item IDs: <prefix>-<4char> (e.g. pm-3042)
  • Status flow: draft โ†’ open โ†’ in_progress โ†’ blocked โ†’ closed/canceled
  • Priority: integers 0โ€“4 only (not strings like "high")
  • Dates: ISO YYYY-MM-DD or relative +1d, +7d โ€” the alias "today" is not recognized
  • To set closed status: pm close <id> "reason" โ€” do not use pm update --status closed
  • To unblock: pm update <id> --unset blocked-by โ€” --blocked-by none is deprecated
  • Diagnostics: pm validate, pm health, pm gc, pm normalize

Installation Issues

ENOTEMPTY error on reinstall

Symptom

npm ERR! code ENOTEMPTY
npm ERR! syscall rename
npm ERR! ENOTEMPTY: directory not empty

Cause

A stale global symlink or partially extracted package tree conflicts with the new install.

Fix

Uninstall completely before reinstalling:

npm uninstall -g @unbrained/pm-cli
npm install -g @unbrained/pm-cli

If the error persists, locate and remove the orphaned directory manually:

npm root -g          # prints e.g. /usr/local/lib/node_modules
rm -rf /usr/local/lib/node_modules/@unbrained/pm-cli
npm install -g @unbrained/pm-cli

Node version requirements

pm-cli requires Node.js 18 or later. Check your version:

node --version

If you are on an older version, upgrade via your package manager or use nvm:

nvm install --lts
nvm use --lts

Initialization Issues

"Tracker is not initialized"

Symptom

Any pm command prints:

Error: Tracker is not initialized. Run `pm init` first.

Fix

Run pm init in your project root (or in the directory you want to track):

pm init

This creates .agents/pm/ and a default settings.json.

If you are inside a monorepo and want a shared tracker, pass an explicit path:

pm init --path /path/to/shared/.agents/pm

Corrupted settings

Symptom

pm-cli starts but behaves erratically, or prints JSON parse errors on startup.

Diagnosis

cat .agents/pm/settings.json

Look for truncated JSON or unexpected characters.

Recovery

  1. Back up the damaged file:
    cp .agents/pm/settings.json .agents/pm/settings.json.bak
    
  2. Delete it and re-initialise:
    rm .agents/pm/settings.json
    pm init
    
  3. Re-apply any custom settings (author name, prefix, format, etc.) that were in the backup.

Common Command Errors

update failures

Invalid option names

Symptom

Error: Unknown option --foo

Run pm update --help to see every accepted flag. Common mistakes:

Wrong Correct
--status closed pm close <id> "reason"
--blocked-by none --unset blocked-by
--priority high --priority 2 (integer 0โ€“4)
--due today --due 2026-05-03 or --due +0d

Status transition errors

Symptom

Error: Invalid status transition: open โ†’ closed

Use the correct command for terminal states:

pm close <id> "reason text"       # โ†’ closed
pm cancel <id> "reason text"      # โ†’ canceled

To move an item back to open from in_progress:

pm update <id> --status open

Only the transitions permitted by the lifecycle are allowed. Run pm validate <id> to see the current lifecycle state and what transitions are available.

close failures

Missing reason

Symptom

Error: A reason is required to close an item.

pm close always requires a reason string:

pm close pm-3042 "Delivered in PR #88"

Validation rules block close

Run pm validate <id> to see exactly which rules are failing. Common blockers:

  • Required fields (title, type) are missing โ€” fill them with pm update.
  • The item has open sub-tasks โ€” close or cancel those first.
  • The item is blocked โ€” unblock it first: pm update <id> --unset blocked-by.

Invalid status values

Do not set closed or canceled via pm update --status. These are terminal states that require a reason and trigger special lifecycle logic:

# Wrong โ€” will be rejected
pm update pm-3042 --status closed

# Correct
pm close pm-3042 "Done โ€” see PR #88"
pm cancel pm-3042 "No longer needed"

Invalid priority values

Priority must be an integer from 0 (lowest) to 4 (highest). String values are not accepted:

# Wrong
pm update pm-3042 --priority high
pm update pm-3042 --priority "critical"

# Correct
pm update pm-3042 --priority 4   # highest
pm update pm-3042 --priority 2   # medium
pm update pm-3042 --priority 0   # lowest

Date format issues

The alias "today" is not recognized. Use ISO dates or relative offsets:

# Wrong
pm update pm-3042 --due today
pm update pm-3042 --due "next week"

# Correct โ€” ISO date
pm update pm-3042 --due 2026-05-03

# Correct โ€” relative offset (days from now)
pm update pm-3042 --due +0d    # today
pm update pm-3042 --due +7d    # one week from today
pm update pm-3042 --due +30d   # one month from today

--blocked-by none is deprecated

Symptom

Warning: --blocked-by none is deprecated

Use --unset instead:

# Deprecated
pm update pm-3042 --blocked-by none

# Correct
pm update pm-3042 --unset blocked-by

Search Issues

Slow search or no results

Search uses an index stored in .agents/pm/. If items were edited outside pm-cli (e.g. by a script or text editor), the index may be stale.

Rebuild the index:

pm reindex

For very large trackers, reindex can take a few seconds. Run it with --verbose to watch progress:

pm reindex --verbose

Missing items in search results

If an item exists on disk but never appears in search, it may have a parse error. Validate it directly:

pm validate <id>

Fix reported errors, then reindex.


Lock Issues

Commands hang or print "lock held by another process"

pm-cli uses a file lock to serialise writes. If a previous process crashed, the lock file can be left behind.

Check for a stale lock

ls .agents/pm/.lock 2>/dev/null && echo "Lock file present"

Clear it safely

pm gc

pm gc removes cache artefacts including stale lock files. It will not delete item data.

If pm gc itself hangs, the lock is held by a running process. Find and stop it:

lsof .agents/pm/.lock    # macOS / Linux

Extension Issues

Extension fails to activate

Symptom

Error: Extension "my-ext" failed to activate

Run the extension doctor for a deep trace:

pm extension doctor --detail deep --trace

This prints activation logs, dependency checks, and the exact error location. Common causes:

  • Extension requires a newer pm-cli version โ€” run pm --version and compare with the extension's peerDependencies.
  • Extension binary is missing from PATH โ€” reinstall the extension package.
  • Incompatible Node version โ€” see Node version requirements.

Listing installed extensions

pm extension list

Removing a broken extension

pm extension remove <name>

Migration / Format Issues

Items fail to parse after upgrade

After a major version bump, the on-disk format may have changed. Run:

pm normalize

pm normalize rewrites every item to the current canonical format without changing any field values. It is safe to run multiple times.

If pm normalize itself crashes on a specific item (e.g. due to non-JSON frontmatter), recover that item manually:

  1. Find the raw file:
    find .agents/pm -name "<id>*"
    
  2. Open it in a text editor and fix the frontmatter so it is valid JSON or valid TOON (whichever format your tracker uses).
  3. Run pm validate <id> until it passes.
  4. Re-run pm normalize.

See MIGRATION.md for version-specific instructions.


Recovery

Restoring an item from history

Every write is appended to .agents/pm/history/<id>.jsonl. You can restore any previous snapshot:

# List available snapshots for an item
pm history <id>

# Restore a specific snapshot by timestamp
pm restore <id> <timestamp>

Timestamps are printed by pm history in ISO 8601 format (e.g. 2026-05-01T14:32:00.000Z).

Recovering a deleted item

Deleted items are removed from the active store but their history file remains. To restore:

pm restore <id> latest

This recreates the item from its most recent history entry.


Getting Help


Troubleshooting local
Report an issue