Skip to content

bwrb delete

Delete notes from your vault with safety checks and bulk mode support.

Terminal window
bwrb delete [options] [query]

Delete operates in three modes:

  • Single-file mode (default): Delete a specific note by name/query
  • Bulk mode: Delete multiple notes matching targeting selectors
  • Scoped mode: Use a query with targeting selectors to narrow the selection
OptionDescription
-t, --type <type>Filter by type
-p, --path <glob>Filter by path glob
-w, --where <expr>Filter by frontmatter expression (repeatable)
-b, --body <query>Filter by Markdown body content; YAML frontmatter is excluded
--id <uuid>Filter by stable note id
-a, --allSelect all notes (required for bulk delete without other targeting)
OptionDescription
-x, --executeActually delete files (default is dry-run for bulk)
--dry-runPreview deletions without removing files
--backupCopy selected files and a manifest under .bwrb/backups/ before deletion
-f, --forceSkip confirmation prompt (single-file or multi-delete)
--picker <mode>Selection mode: auto, fzf, numbered, none
--output <format>Output format: text, json

Bulk delete requires two explicit gates to prevent accidents:

  1. Targeting gate: Must specify at least one selector (--type, --path, --where, --body) OR use --all
  2. Execution gate: Must use --execute to actually delete (dry-run by default)
  3. Confirmation: Deleting more than one file requires explicit confirmation (or --force)
Terminal window
# No query or selectors: enter single-file picker mode
bwrb delete
# Browse notes and select one to preview/delete
# Dry-run: shows what would be deleted
bwrb delete --type task
# Actually deletes
bwrb delete --type task --execute
# Query scoped to targeting (still requires --execute)
bwrb delete --type idea "Specific Name" --execute

Without --force, delete refuses any note that has a direct document fork. The check applies to single, scoped, bulk, execute, and dry-run modes; bulk deletion is all-or-nothing when any selected note is blocked. Duplicate stable IDs also refuse deletion because the parent identity is ambiguous.

Error: Refusing to delete Ideas/Launch Brief.md: fork lineage would be orphaned
Ideas/Launch Brief.md: 1 direct fork child
- Ideas/Launch Brief — concise.md
Use --force to delete anyway; child fork provenance will be left dangling.

JSON refusals include a machine-readable reason (has-fork-children or duplicate-identity) and the affected paths:

{
"success": false,
"error": "Refusing to delete Ideas/Launch Brief.md: fork lineage would be orphaned",
"code": 1,
"data": {
"path": "Ideas/Launch Brief.md",
"reason": "has-fork-children",
"childCount": 1,
"children": [{ "path": "Ideas/Launch Brief — concise.md" }]
}
}

--force is the sole override. It deletes only the selected note: children are not deleted or reparented, and their forked-from value stays intact. A later bwrb audit reports that retained provenance as dangling-forked-from, so the source can still be restored deliberately.

Without --force, bwrb selects the requested notes and then rechecks them while holding the same lineage locks used by fork and adoption. If another process deletes a selected target before that authoritative recheck, the command stops without deleting any of the remaining selected notes and returns exit code 2:

Error: Delete target disappeared while waiting for the lineage lock; retry the command: Ideas/Launch Brief.md

JSON output keeps the numeric exit-code contract and adds stable retry context:

{
"success": false,
"error": "Delete target disappeared while waiting for the lineage lock; retry the command: Ideas/Launch Brief.md",
"data": {
"reason": "target-disappeared",
"retryable": true,
"paths": ["Ideas/Launch Brief.md"]
},
"code": 2
}

Re-resolve the target set before retrying. This is distinct from an initial not-found result: the note existed during selection but vanished while the command was coordinating its write.

Terminal window
# Delete specific note with confirmation
bwrb delete "My Note"
# Skip confirmation
bwrb delete "My Note" --force
# Scripting mode
bwrb delete "My Note" --output json --force
# Create a recoverable backup, then delete
bwrb delete "My Note" --force --backup
# Preview delete without removing (no --force needed)
bwrb delete "My Note" --dry-run --output json

When a note is actually deleted, bwrb also removes the matching path from .bwrb/ids.jsonl.

Terminal window
# Preview deletions (dry-run)
bwrb delete --type task
# Actually delete all tasks
bwrb delete --type task --execute
# Explicit dry-run preview
bwrb delete --type task --dry-run
# Delete all notes in Archive
bwrb delete --path "Archive/**" -x
# Delete by content
bwrb delete --body "DELETE ME" --execute
# Delete with frontmatter filter
bwrb delete --where "status=archived" --execute
# Delete ALL notes (dangerous!)
bwrb delete --all --execute
# Scoped delete (query + targeting)
bwrb delete --type idea "Sample Idea" --execute

When query is ambiguous (single-file mode):

ModeBehavior
autoUse fzf if available, else numbered select (default)
fzfForce fzf (error if unavailable)
numberedForce numbered select
noneError on ambiguity (for non-interactive use)

Deletion removes the source file. With --backup, Bowerbird first copies each selected file byte-for-byte under a timestamped .bwrb/backups/ directory and writes a manifest mapping original paths to their backup copies. JSON output includes the backup path. Without --backup, use version control or another external backup to recover deleted notes.

bwrb audit --fix can offer a delete action for specific issue classes, but it remains interactive-only and never runs in --auto mode. For non-interactive or scripted deletion workflows, use bwrb delete.