Skip to content

initialize_from(resume_at_next_action=False) does not go back to the entrypoint #1020

Open

Description

@enekoreto

With resume_at_next_action=False, loading from a persister behaves the same as True: the app continues after the saved step instead of starting at default_entrypoint.

Current behavior

After loading, get_next_action() returns the action after the last saved step, whether resume_at_next_action is True or False.

Steps to replicate behavior

from burr.core import ApplicationBuilder, State, action, default
from burr.core.persistence import InMemoryPersister


@action(reads=[], writes=["count"])
def counter(state: State) -> State:
    return state.update(count=state.get("count", 0) + 1)


@action(reads=["count"], writes=[])
def done(state: State) -> State:
    return state


persister = InMemoryPersister()


def build(resume_at_next_action):
    return (
        ApplicationBuilder()
        .with_actions(counter=counter, done=done)
        .with_transitions(("counter", "done", default))
        .initialize_from(
            persister,
            resume_at_next_action=resume_at_next_action,
            default_state={},
            default_entrypoint="counter",
        )
        .with_identifiers(app_id="app", partition_key="pk")
        .with_state_persister(persister)
        .build()
    )


build(True).step()  # runs "counter" and saves it
for flag in (True, False):
    app = build(flag)
    print(f"resume_at_next_action={flag}: next action = {app.get_next_action().name}")

Output:

resume_at_next_action=True: next action = done
resume_at_next_action=False: next action = done

Library & System Information

apache-burr 0.43.0 and main (222b32c), Python 3.13, macOS

Expected behavior

docs/concepts/state-persistence.rst describes it as "whether to start where you left off, or go back to the default_entrypoint", so with False the next action should be counter, keeping the loaded state.

Additional context

In ApplicationBuilder._init_state_from_persister the False branch is just pass ("self.start is already set to the default"), but the loaded state still has __PRIOR_STEP, and get_next_action() uses it. The existing tests that use False load from a fake loader or from the local tracker, and neither has __PRIOR_STEP in the loaded state, so they don't catch this. For the same reason the local tracker isn't affected, only persisters (in-memory, SQLite, etc.).

With False, the starting point also depends on how many times a step failed: after one failed attempt the app starts at the failed action, after two at the entrypoint, because the failed-status path removes __PRIOR_STEP when it restarts the action. I mentioned this on the dev list durable-execution thread: https://lists.apache.org/thread/3xp1mfozrxtrc0w8oqh0xh5lgt22kvwj

I'm opening a PR with a fix (calling reset_to_entrypoint() there, like the failed-status branch already does) and tests. If the current behavior is intended, I'm happy to update the docs instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions