Update Task
vault_update_taskUpdate a task's status, priority, description, dates, dependencies, block_id, checklist items, or heading placement in one call. Any combination of these can change together — every field passed is written in a single edit.
Instructions
Update a task's status, priority, description, dates, dependencies, block_id, checklist items, or heading placement in one call. Any combination of these can change together — every field passed is written in a single edit.
Example: vault_update_task({ path: "TASKS.md", block_id: "my-task", status: "done" }) — complete a task; on a Kanban board, auto-moves to the done lane; a recurring task (🔁) spawns its next occurrence Example: vault_update_task({ path: "TASKS.md", block_id: "my-task", recurrence: "every week" }) — make a task recurring (null removes the rule) Example: vault_update_task({ path: "TASKS.md", block_id: "my-task", heading: "Done" }) — move a task to a different heading (lands at the top of the lane by default; the checkbox is unchanged) Example: vault_update_task({ path: "TASKS.md", block_id: "my-task", description: "Updated task name", due: "2026-10-01", scheduled: null }) — change the description, set one date, and clear another Example: vault_update_task({ path: "TASKS.md", block_id: "my-task", status: "in_progress", add_subtasks: ["Design", "Implement", "Test"] }) — start working and add checklist stages Example: vault_update_task({ path: "TASKS.md", line: 42, assign_block_id: "my-task" }) — add a block_id to a task that lacks one Example: vault_update_task({ path: "TASKS.md", block_id: "my-task", heading: "Active", position: 3 }) — move to the 3rd position in a lane
When to use: Any change to an existing task — completing, starting, re-prioritizing, editing text, setting or clearing dates, adding checklist items, assigning block_ids, moving between headings, or reordering within a lane. Use vault_list_tasks first to get identification fields (path + block_id or line). For creating a new task, use vault_create_task instead.
Parameters:
Exactly one of block_id or line is required to identify the task. A sub-task on a Kanban board has no block_id, so re-read its line with vault_list_tasks just before an update by line: each save by the Kanban plugin rewrites the board, and the listing can take a few seconds to catch up with a save.
At least one change is required. Clearing is always explicit null — omitting a field leaves it untouched.
status side effects: Kanban: "done" moves the card and everything nested under it to the done lane (nested checkboxes left as they are); a sub-task stays under its parent. Recurring (🔁), on "done" only: spawns the next occurrence above the completed one, dates advanced per the rule; when the Tasks plugin puts the next recurrence on the line below, the spawn goes there and the completed task's nested lines stay with it. The spawn stays in the source lane with no block_id, 🆔, or ⛔ — follow up with assign_block_id on next_occurrence.line, except on an indented line of a Kanban board. Completing by line is NOT idempotent for recurring tasks (the spawn occupies the old line); prefer block_id. Delete (🏁 delete / [onCompletion:: delete]), on "done": removes the task line and its children instead of moving to done. With 🔁 + 🏁, the spawn is created first, then the completed task is removed. Result carries on_completion_applied: "delete".
recurrence: a rule ending "when done" bases the next occurrence on the completion day. When set together with status "done", the new rule governs the spawn. Setting recurrence to null while completing removes the rule and completes without spawning.
on_completion: passed together with status, the submitted value governs the delete decision — "keep" while completing a "delete" task prevents the deletion.
position: applies to a heading move or an auto-done-lane move; otherwise it reorders the task within its current lane. Omitting position performs no reorder. Ignored when the task is deleted on completion. Not valid on sub-tasks.
Errors: (messages use camelCase names, e.g. assignBlockId for assign_block_id)
"note not found" — path does not exist; check the path with vault_list_notes
"path must end in …" — add the .md extension
"absolute path blocked" / "path traversal blocked" / "hidden path blocked" — use a vault-relative path with no hidden (dot-prefixed) file or folder in it
"exactly one of blockId or line is required" / "blockId and line are mutually exclusive" — pass exactly one of block_id or line
"blockId ... not found" — no task line in the note ends with ^block_id; check the id with vault_list_tasks, or target by line
"blockId ... is inside a fenced code block or comment" — the only lines ending in that ^id sit inside a fenced code block or %% %% comment, which hold no tasks; check the id, or target by line
"blockId ... matches N task lines" — more than one task line ends in the id (the message lists their line numbers); target the intended task by line. To repair on a regular note, give all but one line a new id with assign_block_id. On a Kanban board, where the plugin copied a sub-task's id onto its card, remove the id from the sub-task's line (assign_block_id: null, by line). The card still holds the copied id, so then assign the card's line its original id (links to the card still name it) or a new one
"no task at line N" — line doesn't contain a task checkbox; re-read line numbers with vault_list_tasks, or target by block_id
"line N is inside a fenced code block or comment" — the line is inside a fenced code block or %% %% comment; target a line outside the fence
"checkbox "[c]" is a NON_TASK status" — the task's checkbox character (c) is typed NON_TASK in the Tasks plugin's status settings, so it is not a task; the user must change its type there, then restart the server
"no checkbox symbol for status ..." — the Tasks plugin's status settings have no symbol for the status the message names, and its default character has another type; the user must add one there, then restart the server
"at least one mutation" — no change params provided; pass at least one field to change
"cannot move a sub-task to a heading" — explicit heading on a task nested under another task (depth > 0 in vault_list_tasks); move its parent instead
"cannot reposition a sub-task" — explicit position on a sub-task (sub-tasks move with their parent); reposition the parent instead
"cannot reorder a task that sits above the first heading" — position without a heading on a task before the first section heading; pass heading to move it into a section
"cannot reorder within "X" — the heading appears N times" — same-lane reorder on a card whose heading name is duplicated in the note; rename one section to make it unique
"cannot place at position P under "X" — the heading appears N times" — cross-lane move with an integer position to a heading name that appears more than once; use "top" or "bottom" (they place under the first match), or rename one section to make it unique
"heading "X" not found; available: ..." — target heading doesn't exist; the error lists the note's headings
"multiple done lanes detected" — status "done" on a Kanban board with more than one lane marked complete (a Complete line under its heading); pass heading to pick the lane
"no done lane detected" — status "done" on a Kanban board with no Complete line and no "Done" heading; pass heading explicitly
"blockId ... already exists" / "blockId ... contains invalid characters" — assign_block_id must be unique in the note and match [a-zA-Z0-9-]+
"assignBlockId is not allowed" / "description ends in a block ID" / "subtask ... ends in a block ID" — a new ^id on an indented line of a Kanban board; leave the line without an id and target it by line, and drop any trailing ^id from the text
"invalid date" — a date param fails calendar validation; pass a real YYYY-MM-DD date
"description cannot be empty" / "addSubtasks cannot contain an empty item" — whitespace-only description or checklist item; pass visible text
"description must be a single line" / "addSubtasks items must be a single line" — a task is one file line; a line break in the text would split its metadata onto a line the parser never reads; remove the line breaks
"taskId ... contains invalid characters" / "dependsOn entry ... contains invalid characters" — task_id and every depends_on entry must match [a-zA-Z0-9_-]+ (the Tasks plugin's id grammar)
"unrecognized recurrence rule ..." — the rule text is not Tasks-plugin natural language; written as-is it would silently never recur; use a rule such as "every week" or "every 2 weeks when done"
"concurrent write in progress" — another write to this note is in flight; retry
"properties block …" — the note's properties block can't be read, or a rewrite would lose it; the error says how to repair it
"the note would open with a properties block …" — the edit would leave --- lines at the top of a note with no properties, around text that can't be kept as properties; the error says how to avoid it
Obsidian syntax: The Tasks plugin reads metadata off the END of a task line. When description or add_subtasks text ends in a signifier the plugin's parser recognizes as a field (an emoji field like "🔁 every week", or a Dataview [key:: value] field), with only other recognized fields after it, that text is read back as metadata, not text. Whether it is captured depends on the field's value grammar: 🔁 reads any trailing words as its recurrence rule, while 📅 followed by non-date words stays description text. Captured text can also change the value read back for the field beside it, or add a field the call never set. The write still succeeds either way; when the stored line would read back differently than this call set, the result carries an advisories array naming each divergence; reword the text to avoid one. The ✅/❌ dates a status change adds or removes produce no advisories by themselves. A description signifier that changes how a stamped date parses back is still reported.
Returns: JSON { path, line, description, block_id, heading, subtasks, next_occurrence, changes, advisories, on_completion_applied }.
line is the task's final 1-based line number in the file; after an on_completion delete, the line the task occupied before removal.
description is the current text. block_id and heading reflect the task after the update; block_id is omitted when the task has none, heading when the task sits above the first heading.
subtasks lists each checklist item add_subtasks wrote as { line, description } (omitted when none were added); checklist items are written without a block_id, so line is the handle for a follow-up update.
next_occurrence is present only when a completion spawned a recurring task's next occurrence: { line, description, due?, scheduled?, start? } with only the dates the occurrence has. It carries no block_id, so line is its handle.
changes lists every field applied as "field: before → after", with "(none)" for an absent value. add_subtasks appears as "subtasks", its two sides checklist-item counts, and a spawn adds "next_occurrence: (none) → line N".
advisories (omitted when there are none) lists one sentence for each: a stored line that parses back differently than submitted (see Obsidian syntax above), a duplicate tag removed from the line, or a completed recurring task whose rule yields no next occurrence (unreadable rule text, or a finite rule with no occurrences left).
on_completion_applied is "delete", present only when the effective on_completion was delete (already on the task or set in the same call) and the task was transitioned to done.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| due | No | Due date (YYYY-MM-DD) to set, or null to clear. | |
| line | No | 1-based line number from vault_list_tasks. Fragile if the file changed since the query. | |
| path | Yes | Vault-relative path to the note containing the task (must end in ".md"). Use the exact letter case. | |
| start | No | Start date (YYYY-MM-DD) to set, or null to clear. | |
| format | No | Field format for metadata this call writes; fields it leaves alone keep theirs, so a line can mix formats. Default: auto-detected from .obsidian/ config, falling back to emoji. | |
| status | No | Target status. "done" adds the ✅ date and "cancelled" the ❌ date, when the Tasks plugin's settings stamp them; leaving either status removes its date. | |
| created | No | Created date (YYYY-MM-DD) to set or clear, for corrections. vault_create_task stamps it on every new task. | |
| heading | No | Target heading to move the task to. On Kanban boards this is a lane move; works on any note with headings. Not valid on sub-tasks. | |
| task_id | No | Tasks plugin 🆔 identifier to set, or null to clear — letters, digits, hyphens, and underscores; separate from block_id. | |
| block_id | No | Stable task identifier — the ^block-id at the end of the task line, without the ^. Preferred over line. | |
| position | No | Where within the target heading the task lands. "top" or "bottom" for the extremes; an integer (1-based) for an exact position among the lane's top-level cards (sub-tasks move with their parent and are not counted). Position 1 is the first card. A position past the card count lands directly below the last card (unlike "bottom", which appends after any non-task text at the end of the section). Defaults to "top" on heading and done-lane moves. | |
| priority | No | Priority signifier to set, or null to remove it. | |
| scheduled | No | Scheduled date (YYYY-MM-DD) to set, or null to clear. | |
| depends_on | No | Tasks plugin ⛔ dependency IDs to set (non-empty), or null to clear. | |
| recurrence | No | Tasks plugin 🔁 rule in natural language (e.g. "every week", "every month on the 15th", "every 2 weeks when done") to set, or null to remove it. Completing the task spawns its next occurrence. | |
| description | No | New task description text. Replaces the existing description; metadata fields and block_id are preserved. | |
| add_subtasks | No | Checklist items to append, one indented todo line each, under the task's existing items — never replaces them. Can be combined with any other change; not appended, and not reported, when the same call removes the task (on_completion delete). For full sub-tasks with metadata, use vault_create_task with parent_block_id. | |
| on_completion | No | Tasks plugin 🏁 onCompletion action to set, or null to remove it. "delete" removes the task line on completion; "keep" leaves it in place (which is also the behavior when no 🏁 field exists on the task). Omitting this parameter leaves the field unchanged. | |
| assign_block_id | No | Add or replace the ^block-id on the task line, or null to remove it. Letters, digits, and hyphens only; must be unique within the note. |