# Trigger Looks like its in some loop

**URL:** https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263
**Category:** App Development
**Tags:** trigger, damlhub
**Created:** [April 6, 2022, 8:49pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263 "2022-04-06T20:49:13Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![Max](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/max/32/2128_2.png) [@Max](https://forum.canton.network/u/Max)
#### Post date: [April 6, 2022, 8:49pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/1 "2022-04-06T20:49:13Z")

</div>

This is a follow up to my question about nested maps in a Trigger in this post [Nested MapA for Triggers to Exercise a choice - #2 by bernhard](https://discuss.daml.com/t/nested-mapa-for-triggers-to-exercise-a-choice/4260/2)

My terminal keeps flickering with

```haskell
13:40:57.112 [TriggerRunner-akka.actor.default-dispatcher-9] WARN com.daml.lf.engine.trigger.Runner - Command failed: DAML_AUTHORIZATION_ERROR(8,887fc896): Interpretation error: Error: node NodeId(1) (b0dd5a2d0e56041ea6673a0d0634ae85439f3259b53d7ac1ea5b2ad22026953f:Account:AssetHoldingAccount) requires authorizers b, but only a,d were given, code: 3 , context: {triggerDefinition: "b0dd5a2d0e56041ea6673a0d0634ae85439f3259b53d7ac1ea5b2ad22026953f:Trigger:autoSendExampleAssetAccountProposal"} 
13:40:57.112 [TriggerRunner-akka.actor.default-dispatcher-9] DEBUG daml.tracelog - [unknown source]: "TRIGGERED"  
^C13:40:57.117 [TriggerRunner-akka.actor.default-dispatcher-10] WARN com.daml.lf.engine.trigger.Runner - Command failed: Channel shutdownNow invoked, code: 14 , context: {triggerDefinition: "b0dd5a2d0e56041ea6673a0d0634ae85439f3259b53d7ac1ea5b2ad22026953f:Trigger:autoSendExampleAssetAccountProposal"} 
13:40:57.118 [TriggerRunner-akka.actor.default-dispatcher-10] DEBUG daml.tracelog - [unknown source]: "TRIGGERED"  
13:40:57.118 [TriggerRunner-akka.actor.default-dispatcher-10] WARN com.daml.lf.engine.trigger.Runner - Command failed: Channel shutdownNow invoked, code: 14 , context: {triggerDefinition: "b0dd5a2d0e56041ea6673a0d0634ae85439f3259b53d7ac1ea5b2ad22026953f:Trigger:autoSendExampleAssetAccountProposal"} 
13:40:57.119 [TriggerRunner-akka.actor.default-dispatcher-10] DEBUG daml.tracelog - [unknown source]: "TRIGGERED"  

```

The trigger is below. My goal is here is create an `AssetHoldingAccountRequest` for each new user (this is done on the frontend) , and I only want the trigger to run when there is a non-empty list of `AssetHoldingAccountRequests`, because I map through these requests, exercising the `Accept` choice. At the moment, it seems that the trigger is run in a loop.

Per the below, this template should be archived once “Accept” is exercised by the owner/admin party.

```haskell
template AssetHoldingAccountRequest with
    recipient: Party
    owner: Party
  where 
    signatory recipient
    observer owner
    choice Accept: ContractId AssetHoldingAccountProposal
      with assetHoldingAccount: ContractId AssetHoldingAccount
      controller owner
      do
         exercise assetHoldingAccount Invite_New_Asset_Holder with 
          recipient = recipient

```

Trigger here

```haskell
module Trigger where

import Account
import qualified Daml.Trigger as T
import DA.Foldable
import DA.Next.Map (Map)
import DA.Optional (whenSome)
import DA.Action
import qualified DA.List.Total as List

autoSendExampleAssetAccountProposal: T.Trigger ()
autoSendExampleAssetAccountProposal = T.Trigger 
 { initialize = pure (),
  updateState = \_ -> pure (),
  registeredTemplates = T.AllInDar,
  rule = \p -> do
    asset_holding_account_requests <- T.query @Account.AssetHoldingAccountRequest
    let isNotMe = (\requests -> requests.recipient /= p)
    let notMeList = filter (\(_, contract) -> isNotMe contract) asset_holding_account_requests
    let requests = map fst notMeList

    assetAccounts <- T.query @Account.AssetHoldingAccount
    let isET = (\account -> account.assetType.symbol == "ET")
    let etAccounts = filter (\(_, contract) -> isET contract) assetAccounts

    let cids = map fst etAccounts
    let commands = map(\request -> map(\cid -> T.exerciseCmd request Accept with assetHoldingAccount = cid) cids ) requests
    T.emitCommands ( DA.Foldable.concat commands)[]
    debug $ "TRIGGERED",
  heartbeat = None
}

```

(some additional context)  
The lines below is actually a work around, what I actually want to do is grab 1 account with a key

```haskell
 let isET = (\account -> account.assetType.symbol == "ET")
 let etAccounts = filter (\(_, contract) -> isET contract) assetAccounts

```

I suspect it’s triggering non stop due to the line

```haskell
    let commands = map(\request -> map(\cid -> T.exerciseCmd request Accept with assetHoldingAccount = cid) cids ) requests

```

Any ideas? I previously was mapping over the list of Cids (the length should be always 1), and that’s why I was thinking perhaps since it was always non-empty, the trigger would keep firing.

But I since reversed the mapping, so we are mapping the requests in the outer map. So technically if all the requests were archived through “Accept” It shouldn’t keep firing right?

---

<div class="post-metadata">

### Author: ![Stephen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/stephen/32/102_2.png) [@Stephen](https://forum.canton.network/u/Stephen)
#### Post date: [April 6, 2022, 10:07pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/2 "2022-04-06T22:07:05Z")

</div>

If you think you are duplicate-exercising due to pending _consuming_ commands not being complete yet, the first thing to try is to pass a second argument to `emitCommands` rather than `[]`. `(map toAnyContractId cids)` should suffice in this case.

More complex cases may require you to use a state instead of `()` for your trigger type. But I think this is unnecessary here, as you do not expect to be able to exercise more than one choice on a given contract, and do not expect to be able to query for it more than once.

I also suggest setting [a proper value for `registeredTemplates`](https://docs.daml.com/2.0.0/triggers/index.html#codecell2) rather than `AllInDar`; this will cut down on spurious rule executions and make it easier to diagnose some issues.

---

<div class="post-metadata">

### Author: ![Max](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/max/32/2128_2.png) [@Max](https://forum.canton.network/u/Max)
#### Post date: [April 6, 2022, 11:19pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/3 "2022-04-06T23:19:04Z")

</div>

I tried `map toAnyContractId cids)`, and registered the template instead of AllInDar, I still get a loop.

any idea what this line, in the error below?  
snippet:

```haskell
Command failed: MISSING_FIELD(8,0d2d02c0): The submitted command is missing a mandatory field: commands, code: 3 , context: {triggerDefinition: "9ee442348f756d08624e2e5eb937407a684101d0a5f0efdc9b6e5551412f1955:Trigger:autoSendExampleAssetAccountProposal"}

```

Full message that is on loop in the terminal

```haskell
16:16:59.908 [TriggerRunner-akka.actor.default-dispatcher-5] WARN com.daml.lf.engine.trigger.Runner - Command failed: MISSING_FIELD(8,0d2d02c0): The submitted command is missing a mandatory field: commands, code: 3 , context: {triggerDefinition: "9ee442348f756d08624e2e5eb937407a684101d0a5f0efdc9b6e5551412f1955:Trigger:autoSendExampleAssetAccountProposal"} 

```

---

<div class="post-metadata">

### Author: ![Max](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/max/32/2128_2.png) [@Max](https://forum.canton.network/u/Max)
#### Post date: [April 6, 2022, 11:22pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/4 "2022-04-06T23:22:45Z")

</div>

This is the updated code, i tried the dedup, but that didn’t help.  
I also noticed that the debug is not printing anything except for “TRIGGERED”,  
debug requests, and debug cids aren’t printed.

```haskell
autoSendExampleAssetAccountProposal: T.Trigger ()
autoSendExampleAssetAccountProposal = T.Trigger 
 { initialize = pure (),
  updateState = \_ -> pure (),
  registeredTemplates = T.RegisteredTemplates [T.registeredTemplate @Account.AssetHoldingAccountRequest],
  rule = \p -> do
    asset_holding_account_requests <- T.query @Account.AssetHoldingAccountRequest
    let isNotMe = (\requests -> requests.recipient /= p)
    let notMeList = filter (\(_, contract) -> isNotMe contract) asset_holding_account_requests
    let requests = map fst notMeList
    debug requests
    assetAccounts <- T.query @Account.AssetHoldingAccount
    let isET = (\account -> account.assetType.symbol == "ET")
    let etAccounts = filter (\(_, contract) -> isET contract) assetAccounts
  
    let cids = map fst etAccounts
    debug cids
    let commands = map(\request -> map(\cid -> T.exerciseCmd request Accept with assetHoldingAccount = cid) cids ) requests
    debug cids
    T.emitCommands ( DA.Foldable.concat commands)(map T.toAnyContractId requests)
    debug $ "TRIGGERED",
  heartbeat = None
}

```

---

<div class="post-metadata">

### Author: ![Max](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/max/32/2128_2.png) [@Max](https://forum.canton.network/u/Max)
#### Post date: [April 6, 2022, 11:31pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/5 "2022-04-06T23:31:17Z")

</div>

When I comment out the T.emitCommands,  
I can see in the terminal that the trigger runs properly (thought without any updates to the ledger), and there is no infinity looping.

```haskell
16:30:16.427 [TriggerRunner-akka.actor.default-dispatcher-8] INFO com.daml.lf.engine.trigger.Runner - Trigger is running as a with readAs=[] , context: {triggerDefinition: "1d928f21b2ffdeff8de66903643d165a9086e7d7b5242141b260877ca4edf360:Trigger:autoSendExampleAssetAccountProposal"} 
16:30:16.487 [TriggerRunner-akka.actor.default-dispatcher-8] DEBUG daml.tracelog - [unknown source]: []  
16:30:16.490 [TriggerRunner-akka.actor.default-dispatcher-8] DEBUG daml.tracelog - [unknown source]: []  
16:30:16.491 [TriggerRunner-akka.actor.default-dispatcher-8] DEBUG daml.tracelog - [unknown source]: []  
16:30:16.492 [TriggerRunner-akka.actor.default-dispatcher-8] DEBUG daml.tracelog - [unknown source]: "TRIGGERED"  

```

---

<div class="post-metadata">

### Author: ![Max](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/max/32/2128_2.png) [@Max](https://forum.canton.network/u/Max)
#### Post date: [April 6, 2022, 11:39pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/6 "2022-04-06T23:39:06Z")

</div>

The solution in this post seems to stop the loop at the start up of the trigger

> [@Error "Missing field: commands" when running trigger](https://discuss.daml.com/t/error-missing-field-commands-when-running-trigger/200/2):
>
> I’m somewhat guessing here but I believe that cmds is probably empty. The ledger API does not accept empty list of commands. If that is the issue you can simply wrap it in when: when (not (null cmds)) (emitCommands cmds pendings) Might make sense to modify emitCommands to handle this automatically.

But as soon as a new contract is created for `AssetHoldingAccountRequest`, the loop starts.

---

<div class="post-metadata">

### Author: ![cocreature](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/cocreature/32/36_2.png) [@cocreature](https://forum.canton.network/u/cocreature)
#### Post date: [April 7, 2022, 6:41pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/7 "2022-04-07T18:41:15Z")

</div>

Can you share the code you are using now?

---

<div class="post-metadata">

### Author: ![Max](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/max/32/2128_2.png) [@Max](https://forum.canton.network/u/Max)
#### Post date: [April 7, 2022, 7:00pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/8 "2022-04-07T19:00:13Z")

</div>

The below fixes the infinity triggering. But there is one more thing described below

```haskell
autoSendExampleAssetAccountProposal: T.Trigger ()
autoSendExampleAssetAccountProposal = T.Trigger 
 { initialize = pure (),
  updateState = \_ -> pure (),
  registeredTemplates = T.RegisteredTemplates [T.registeredTemplate @AssetHoldingAccountRequest, T.registeredTemplate @AssetHoldingAccount],
  rule = \p -> do
    asset_holding_account_requests <- T.query @AssetHoldingAccountRequest
    let isNotMe = (\requests -> requests.recipient /= p)
    let notMeList = filter (\(_, contract) -> isNotMe contract) asset_holding_account_requests
    let requests = map fst notMeList

    debug ("requests",requests)
    assetAccounts <- T.query @AssetHoldingAccount
    debug ("assetAccounts", assetAccounts)
    let isET = (\account -> account.assetType.symbol == "ET" && account.assetType.issuer == p)
    let etAccounts = filter (\(_, contract) -> isET contract) assetAccounts
    let cids = map fst etAccounts
    
    
    unless ( DA.Foldable.null requests && DA.Foldable.null cids ) do
      let (cid, c) = head etAccounts

      mapA_(\request -> T.dedupExercise request Accept with assetHoldingAccount = cid) requests
      pure()
    debug $ "TRIGGERED",
  heartbeat = None
}

```

There is a gotcha here that causes the trigger to fail. And that is

```haskell
let (cid, c) = head etAccounts

```

There is a chance that the cid is empty, and that fails the trigger. So I need to ensure that I have created an AssetHoldingAccount, with account.assetType.symbol == “ET”,

Is there a way to prevent the trigger from running if that contract doesn’t exist yet?

---

<div class="post-metadata">

### Author: ![cocreature](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/cocreature/32/36_2.png) [@cocreature](https://forum.canton.network/u/cocreature)
#### Post date: [April 7, 2022, 7:03pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/9 "2022-04-07T19:03:44Z")

</div>

How about something like this:

```haskell
    unless ( DA.Foldable.null requests && DA.Foldable.null cids ) do
      case etAccounts of
        [] -> pure ()
        (cid, c) :: _ ->
          mapA_(\request -> T.dedupExercise request Accept with assetHoldingAccount = cid) requests

```

That way your trigger simply does nothing if the list is empty.

---

<div class="post-metadata">

### Author: ![Stephen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/stephen/32/102_2.png) [@Stephen](https://forum.canton.network/u/Stephen)
#### Post date: [April 7, 2022, 7:05pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/10 "2022-04-07T19:05:52Z")

</div>

I also suggest using `find` instead of `filter` to define `etAccounts` (which would probably be `etAccount` then).

You also might then shift this lookup to earlier in the `rule` definition, using `whenSome` to guard the rest of the rule to only figure your requests in case the `etAccount` is defined.

---

<div class="post-metadata">

### Author: ![Max](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/max/32/2128_2.png) [@Max](https://forum.canton.network/u/Max)
#### Post date: [April 7, 2022, 7:29pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/11 "2022-04-07T19:29:49Z")

</div>

Thank guys! I will give it a try.

---

<div class="post-metadata">

### Author: ![Pris17](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/pris17/32/2078_2.png) [@Pris17](https://forum.canton.network/u/Pris17)
#### Post date: [September 13, 2022, 9:21am UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/12 "2022-09-13T09:21:21Z")

</div>

@cocreature How to use (cid, c) :: \_ in case? I want to create another template by using some values from contract c. How to extract values from c?

---

<div class="post-metadata">

### Author: ![Gary\_Verhaegen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/gary_verhaegen/32/81_2.png) [@Gary\_Verhaegen](https://forum.canton.network/u/Gary_Verhaegen)
#### Post date: [September 13, 2022, 10:21am UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/13 "2022-09-13T10:21:46Z")

</div>

Hi @Pris17,

Let’s first take a quick look at what that expression means:

```haskell
case someExpr of
  [] -> undefined
  (cid, c) :: _ -> undefined

```

This means that:

- `someExpr` is an expression of type `[(a, b)]`, i.e. a list of which the elements are tuples of two elements. From that expression alone we can’t tell anything about the element types, but from additional context we know they’re something like `(ContractId c, c)`.
- `(cid, c) :: _` means “in the case where there is at least one element, name the first value of the pair `cid` and the second value `c`, and disregard all other elements (`:: _`)”.

In this case, `cid` is an opaque, “atomic” value, so there is no way (or need) to “dig into” it. However, `c` is itself a record of a type that corresponds to a template, and is thus a compound value.

There are a few ways to dig into it, but we need a slightly more concrete example to illustrate them. Let’s assume we have a template definition:

```haskell
template Example
  with
    a : Text
    b : Int
    c : Party
  where
    signatory c

```

Now, if `c` happens to be of type `Example`, here are a few ways of accessing its values. First off, we can use so-called “dot notation” to access its fields:

```haskell
usingDot : [(ContractId Example, Example)] -> Script ()
usingDot listOfContracts = case listOfContracts of
  [] -> pure ()
  (cid, c) :: _ -> do
    debug $ c.a <> " (id: " <> show c.c <> ") is " <> show c.b <> " years old"
    return ()

```

If you want to bind all of the fields and give them custom names, you can use the constructor directly:

```haskell
usingConstructor : [(ContractId Example, Example)] -> Script ()
usingConstructor listOfContracts = case listOfContracts of
  [] -> pure ()
  (cid, Example name age id) :: _ -> do
    debug $ name <> " (id: " <> show id <> ") is " <> show age <> " years old"
    return ()

```

You can also use field destructuring, which lets you pick specific fields, if you don’t need all of them:

```haskell
usingDestructuring : [(ContractId Example, Example)] -> Script ()
usingDestructuring listOfContracts = case listOfContracts of
  [] -> pure ()
  (cid, Example { a = name, b}) :: _ -> do
    debug $ name <> " is " <> show b <> " years old"
    return ()

```

Here, you can see two different syntaxes to access a field: `a = name` uses the record field `a` but renames it locally to `name`, whereas `b` here gets the field and keeps its name.

Finally, you can also bring all of the fields directly in scope, which I personally don’t like, using the splat operator `..`:

```haskell
usingSplat : [(ContractId Example, Example)] -> Script ()
usingSplat listOfContracts = case listOfContracts of
  [] -> pure ()
  (cid, Example {..}) :: _ -> do
    debug $ a <> " (id: " <> show c <> ") is " <> show b <> " years old"
    return ()

```

I’m not an expert so can’t claim this list is exhaustive, but hopefully you find at least one option you like among those.

---

<div class="post-metadata">

### Author: ![Pris17](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/pris17/32/2078_2.png) [@Pris17](https://forum.canton.network/u/Pris17)
#### Post date: [September 13, 2022, 11:26am UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/14 "2022-09-13T11:26:49Z")

</div>

Thanks @Gary_Verhaegen for the detailed explanation.  
This helps me to understand the expression quite well and implement it accordingly. I will try out and ask for any help if I get stuck.

---

<div class="post-metadata">

### Author: ![Pris17](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/pris17/32/2078_2.png) [@Pris17](https://forum.canton.network/u/Pris17)
#### Post date: [September 14, 2022, 10:22am UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/15 "2022-09-14T10:22:13Z")

</div>

@Gary_Verhaegen  
`usingDot : [(ContractId Example, Example)] -> Script () usingDot listOfContracts = case listOfContracts of [] -> pure () (cid, c) :: _ -> do debug $ c.a <> " (id: " <> show c.c <> ") is " <> show c.b <> " years old" return ()`

In above e.g. if I want to process all the elements in the list then how should be the 2nd switch written?

```haskell
(cid, c) :: _ -> 

```

instead of \_, what needs to be written and how to then process all the elements of the list?

---

<div class="post-metadata">

### Author: ![Gary\_Verhaegen](https://yyz2.discourse-cdn.com/flex034/user_avatar/forum.canton.network/gary_verhaegen/32/81_2.png) [@Gary\_Verhaegen](https://forum.canton.network/u/Gary_Verhaegen)
#### Post date: [September 14, 2022, 4:07pm UTC](https://forum.canton.network/t/trigger-looks-like-its-in-some-loop/4263/16 "2022-09-14T16:07:55Z")

</div>

There are multiple ways to do that, and the best approach will depend on what you’re trying to do in a slightly broader sense. Can you elaborate a little bit more on what your use-case is?
