You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
track_tasks creates the first card before refusing the second item of the batch #2597
Read on current main d9ade2875876c543679edc4f3f1ecf6ef25133f7 (2026-11-07). Defect class: a request that ends in a refusal still leaves a partial write behind, because the handler creates records before it finishes validating.
Write that lands early — core/src/host/tasks.js:1129 (makeTask, called from trackBotTasks)
The batch loop starts at core/src/host/tasks.js:1135 and validates each item in turn, and the whole batch save() runs only after the loop. A later item's refusal — line 1144, if (ask && column === 'done') throw invalid('A task that needs an answer cannot be done') — unwinds after the earlier card is already in state.tasks; the only removal is the if (isNew) delete store()[task.id] around writeContract and it is not reached.
throws A task that needs an answer cannot be done; the caller is told the batch failed.
Who controls the input — the Bot's own track_tasks body (up to 20 items), which a group round or a workflow brief drives. column, ask and title are caller strings; the leftover card is in state.tasks.
Red — whole store compared before/after (node --import ./test/harness-resolve.mjs --test test/audit-partial-write-b.test.js):
error: |-
the refused request left the store untouched
+ actual - expected
+ {
+ 'task-b10957221a695125': {
+ id: 'task-b10957221a695125',
+ ownerBotId: 'd1',
+ status: 'open',
+ title: 'First card',
...
- {}
# pass 0
# fail 1
assert.equal(saves(), 0) passed: nothing was saved, but the refused batch left a card in memory.
Expected — a refused batch creates nothing: either every item is validated before the first makeTask, or the batch is undone on the way out.
Smallest fix — a first pass over items that runs every per-item check (readColumn, title, ask/answer, the ask && column === 'done' rule) before the write loop; alternatively wrap the loop in try/catch and delete the create rows recorded in saved from store() before re-throwing.
Activity
HugoXK commentedon Nov 7, 2026
Claim
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: f183d8ecfe3f404ebaac66ae4292cc1d
Branch: dev/2597-track-tasks-creates-the-first-card-befor
Base: fd568ab
At: 2026-11-07T09:51:56Z
fix(tasks): a refused track_tasks batch leaves no card behind (ThinkF…
Release v0.2.26 (ThinkFlowLab#2627)
track_tasks: a refused batch save leaves the board mutated, so a ghos…