Decides effect not allowed by it's context please help

I have a function that uses the decides effect that I need to connect to a button interaction subscription so I tried putting it in the Subcribe(function) thing and that didn’t work so I used a handler and now that won’t work either because it says my function has a decides effect that isn’t allowed by it’s context I have tried everything I can think of and everything I could put between them ends up with the same error so I’m not sure what to do now

@editable Button : button_device = button_device{}

HandleButtonPush(Agent : agent) : void =
        spawn:    #I'm not sure if spawn is even needed in this but I usually use it for handlers and even if I remove it it's the same error.
            Function[Agent] # This invocation calls a function that has the 'decides' effect, which is not allowed by its context.(3512)

Function(Agent : agent)<decides> : void =

OnBegin<override>()<suspends>:void=
        Button.InteractedWithEvent.Subscribe(HandleButtonPush)

Decides effects have to be invoked from a “failure” context. Here is some documentation on failure and the contexts. Failure

In the case you’ve outlined I believe you should be able to do this:

HandleButtonPush(Agent : agent) : void =
    spawn:
        if { Function[Agent] }
1 Like

Hello, <decides> functions are failable, so you need to call them in a failable context :

# Example 1
if(Function[Agent]):
    # Do stuff

# Example 2 (if you're function returns void)
option{Function[Agent]}

Also the spawn expression is used to run code asynchronously in a separate “thread” (so that the code below it is executed before the spawn even finishes)

You can also use it to call <suspends> function in a non <suspends> function

1 Like

@Incredulous_Hulk @im_a_lama thank you for your answers! They did get rid of my decides error but now I have new errors :frowning:

HandleButtonPush(Agent : agent) : void =
        spawn:
            if { Function[Agent] } #Non-async argument. `spawn` expects an async argument (currently must be a single coroutine call) to run concurrently.(3538) This invocation calls a function that has the 'no_rollback' effect, which is not allowed by its context.(3512)
HandleButtonPush(Agent : agent) : void =
        if { Function[Agent] } # This invocation calls a function that has the 'no_rollback' effect, which is not allowed by its context.(3512)
HandleButtonPush(Agent : agent) : void =
        option{Function[Agent]} # This invocation calls a function that has the 'no_rollback' effect, which is not allowed by its context.(3512)

You can add a <transacts> specifier before your decides specifier like this :

    Function(Agent : agent)<transacts><decides> : void =

I think you always have to put both at the same time ? I don’t remember, but it works :+1:

1 Like

That’s correct!
As of now, you should mark any <decides> function with <transacts> (or <computes>) as well, see 4.2 in our Verse Style Guide.

This is because user-defined functions are marked <no_rollback> by default (for now). Since any failure context (for example, the expression inside an if) must be allowed to rollback (i.e. is transactable), you must specify <transacts> too.

3 Likes