Daml Script fails when top level type signature missing

If I remove the top-level type signature of a Daml Script, I get:

Exception in thread "main" java.lang.IllegalArgumentException: Expected type 'Daml.Script.Script a' but got TForall((r,KStar),TApp(TApp(TBuiltin(BTArrow),TSynApp(d4e50d51c79ff5c165dc1eb06091b05ab6e7eafc51552faf1a67df578b783433:DA.Internal.Record:HasField,ImmArray(TApp(TTyCon(d58cf9939847921b2aab78eaa7b427dc4c649d25e6bee3c749ace4c3f52f5c97:DA.Internal.PromotedText:PromotedText),TStruct(Struct((_institution,TBuiltin(BTUnit))))),TVar(r),TBuiltin(BTText)))),TApp(TApp(TBuiltin(BTArrow),TSynApp(d4e50d51c79ff5c165dc1eb06091b05ab6e7eafc51552faf1a67df578b783433:DA.Internal.Record:HasField,ImmArray(TApp(TTyCon(d58cf9939847921b2aab78eaa7b427dc4c649d25e6bee3c749ace4c3f52f5c97:DA.Internal.PromotedText:PromotedText),TStruct(Struct((_agents,TBuiltin(BTUnit))))),TVar(r),TApp(TBuiltin(BTList),TBuiltin(BTText))))),TApp(TApp(TBuiltin(BTArrow),TSynApp(d4e50d51c79ff5c165dc1eb06091b05ab6e7eafc51552faf1a67df578b783433:DA.Internal.Record:HasField,ImmArray(TApp(TTyCon(d58cf9939847921b2aab78eaa7b427dc4c649d25e6bee3c749ace4c3f52f5c97:DA.Internal.PromotedText:PromotedText),TStruct(Struct((_banks,TBuiltin(BTUnit))))),TVar(r),TApp(TBuiltin(BTList),TBuiltin(BTText))))),TApp(TApp(TBuiltin(BTArrow),TVar(r)),TApp(TTyCon(052c972215f83506001cb4f5503dc49cce0fc52011b2aa1bf8a7158683877666:Daml.Script:Script),TTyCon(425a4e461801ee155c0fad20ac7a090ec9450097c1ba8484fe02fc532d8c90c5:M1.M2.M3.M4:Parties)))))))
  at com.daml.lf.data.package$.$anonfun$assertRight$1(package.scala:10)
  at scala.util.Either.fold(Either.scala:192)
  at com.daml.lf.data.package$.assertRight(package.scala:10)
  at com.daml.lf.engine.script.Runner$.run(Runner.scala:300)
  at com.daml.lf.engine.script.RunnerMain$.$anonfun$main$13(RunnerMain.scala:112)
  at scala.concurrent.Future.$anonfun$flatMap$1(Future.scala:307)
  at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:41)
  at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
  at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:56)
  at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:93)
  at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
  at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:85)
  at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:93)
  at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:53)
  at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:48)
  at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
  at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
  at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
  at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175)
daml-helper: Received ExitFailure 1 when running
Raw command: java -Dlogback.configurationFile=/home/daml/.daml/sdk/1.13.1/daml-sdk/script-logback.xml -jar /home/daml/.daml/sdk/1.13.1/daml-sdk/daml-sdk.jar script --ledger-host localhost --ledger-port 6865 --dar target/test.dar --script-name M1.M2.M3.M4:allocate --input-file displayNames.json --output-file parties.json

Could this be a bug in the SDK?

Unfortunately I cannot reproduce it in a minimum working example. Although enabling the type signature resolves this, I think it still worth having this question here.

The relevant code segment:

data Parties = Parties with
  institution: Party
  agents: [Party]
  banks: [Party]

data DisplayNames = DisplayNames with
  institution: Text
  agents: [Text]
  banks: [Text]

-- uncomment to fix the error: allocate: DisplayNames -> Script Parties
allocate displayNames = script do
  institution <- allocateParty displayNames.institution
  agents <- mapA allocateParty displayNames.agents
  banks <- mapA allocateParty displayNames.banks
  return Parties{..}
1 Like

This is a consequence of record field overloading. If you look at the type that gets inferred here, allocate has the following type:

allocate : (HasField "institution" a, HasField "agents" a, HasField "banks" a) => a -> Script Parties

Daml Script needs a concrete input type with no type variables which is why this blows up.

The error maybe could be better but we’re talking about Daml-LF types here not Daml types where typeclasses are already desugared and that somewhat inherently leaks into error messages.

2 Likes