Reschedule a branch#
Reschedule one task and the work that depends on it, and leave the rest of the project where it is.
The scope starts at the task you name. It takes in that task's summary ancestors and descendants, then every task that follows it through links, together with their own ancestors and descendants. With inclusive: true (the default), the scope also reaches back through links to the tasks that lead into it. Tasks outside the scope keep their dates, but they still push the tasks inside it.
Steps#
-
Serialize the solve options with a
subtreethat names the task the branch starts from.inclusivedefaults totrue:const = ;To keep the predecessors of
designwhere they are and reschedule onlydesignand the work after it, setinclusive: false:const = ; -
Pass the options to
solve. Send the data string on the first load, orundefinedto reschedule the current state. For a one-shot job without a handle,scheduletakes the same options:const = ; -
Check
ok, then write the entries ofresult.updatesback to your model. Each entry is a task in the scope that moved. After asolve, the scoped dates become the accepted baseline.
The full example below has two independent chains, backend → api and design → ui. Both successors start too early. The scoped solve fixes only the design branch:
const = ;
const = ;
const = ;
const = new;
Preview a branch#
To see what rescheduling a branch would do without changing the project, set the same subtree in the options of preview:
const = ;
The preview scope applies to that call only. It doesn't touch the baseline or the cached solve result. A preview scope can also name a task that the same change set adds.
Things to know#
- Tasks outside the scope don't move until you solve them. In the example, the next
project.solve(undefined, "{}")moves onlyapi, becauseuiis already accepted. - The result cache uses the whole options object as its key. A different
subtreereplans from the accepted dates. The samesubtreeagain returns the cached result. - With
config.gap_behavior: "compress"andconfig.apply_constraints: false, the task you name never moves earlier than its current dates. Withinclusive: true, its predecessors in the scope keep that floor too. - With
includeUnchanged, a scoped solve reports every task in the scope, plus the out-of-scope tasks a sparse scoped solve would report. - On a project with a dependency cycle, nothing is scheduled, scoped or not. Check
result.cycles. - An unknown or unscheduled task in
subtree.taskreturns avalidationerror at pathsubtree.task, with the messageunknown or unscheduled scope task. The project keeps its previous state and cached result. See Error handling.
Result#
Run the example with node. It prints one line. Only ui moves, to start after design ends. api still overlaps backend:
ui 2026-01-04 00:00..2026-01-05 00:00
Without subtree, the same solve also moves api to 2026-01-03 00:00.