Skip to content

load() can throw and install a poisoned definition instead of returning LoadOutcome #281

Description

@CameronBrooks11

BTRuntime::load() contracts to return LoadOutcome{ok, error} and preserve the previously-active definition on failure. It can instead throw, after having already committed the new definition.

The try/catch in load() wraps only createTreeFromFile. The subsequent populate_blackboard(*tree_) call sits outside it, and after tree_, tree_path_, loaded_def_bytes_, version_, and tree_loaded_ = true have all been assigned.

populate_blackboard does blackboard->set(kBTServiceContextKey, services). A tree that remaps a port onto anolis.bt_service_context declares that key with a different type at build time, so the set throws BT::LogicError. The tree builds fine — the collision only appears when the runtime writes the service context.

Result: load() throws instead of returning, and the runtime is left with tree_loaded_ = true and a definition that cannot be ticked. The caller's error path never runs and the previous good definition is gone.

Reproduced during review of #279 with:

<GetParameter param="x" value="{anolis.bt_service_context}"/>

Fix is to move populate_blackboard inside the guarded region, or to stage it before the commit so a failure preserves the previous definition like every other load failure does.

Found while reviewing #280; not introduced by it.

Activity

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions