Cannot disable party completely. Ask your identity manager for help

I am assembling a demo of Migrating Party to Another Participant Node but getting a runtime exception.

When I run this step in the migration process from a Canton script…

repair.party_migration.step1_hold_and_store_acs(
    alice, participant1, participant2.id, gzipfile)

… I get this error:

java.lang.Exception:
Cannot disable party alice::1220eceb59a0... completely.
Ask your identity manager for help.

Here are some more details that might be helpful:

more of the script
participant1.parties.list().find(p => p.party.toProtoPrimitive.startsWith("alice::"))
match {
  case None => logger.error("Cannot find alice on participant1.")
  case Some(result) =>
    val alice = result.party
    logger.info("Found alice on participant1.")

    // preparation
    val mrrp = mydomain.service.get_max_rate_per_participant
    mydomain.service.set_max_rate_per_participant(0)
    participant1.domains.disconnect("mydomain")
    participant2.domains.disconnect("mydomain")
    val gzipfile = "/canton/host/configs/alice.acs.gz"
    
    // migration
    logger.info("Beginning step one.")
    repair.party_migration.step1_hold_and_store_acs(
      alice, participant1, participant2.id, gzipfile)
              :
              :
full exception stack trace
2024-01-29 18:49:01 2024-01-29 23:49:01,195 [main] ERROR c.d.canton.ConsoleScriptRunner - Script execution failed: java.lang.Exception: Cannot disable party alice::1220eceb59a0... completely. Ask your identity manager for help.
2024-01-29 18:49:01     at com.digitalasset.canton.console.macros.RepairMacros$party_migration$.haltParty(RepairMacros.scala:336)
2024-01-29 18:49:01     at com.digitalasset.canton.console.macros.RepairMacros$party_migration$.step1_hold_and_store_acs(RepairMacros.scala:515)
2024-01-29 18:49:01     at ammonite.canton.interpreter.canton$minusscript$.<clinit>(migrate.canton:24)
2024-01-29 18:49:01     at ammonite.canton.interpreter.canton$minusscript.$main(migrate.canton)
2024-01-29 18:49:01     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2024-01-29 18:49:01     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
2024-01-29 18:49:01     at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2024-01-29 18:49:01     at java.base/java.lang.reflect.Method.invoke(Method.java:566)
2024-01-29 18:49:01     at ammonite.runtime.Evaluator$$anon$1.$anonfun$evalMain$1(Evaluator.scala:108)
2024-01-29 18:49:01     at ammonite.util.Util$.withContextClassloader(Util.scala:24)
2024-01-29 18:49:01     at ammonite.runtime.Evaluator$$anon$1.evalMain(Evaluator.scala:90)
2024-01-29 18:49:01     at ammonite.runtime.Evaluator$$anon$1.$anonfun$processScriptBlock$1(Evaluator.scala:153)
2024-01-29 18:49:01     at ammonite.util.Catching.map(Res.scala:117)
2024-01-29 18:49:01     at ammonite.runtime.Evaluator$$anon$1.processScriptBlock(Evaluator.scala:150)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.$anonfun$processSingleBlock$5(Interpreter.scala:344)
2024-01-29 18:49:01     at ammonite.util.Res$Success.flatMap(Res.scala:62)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.$anonfun$processSingleBlock$4(Interpreter.scala:335)
2024-01-29 18:49:01     at ammonite.util.Res$Success.flatMap(Res.scala:62)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.$anonfun$processSingleBlock$2(Interpreter.scala:329)
2024-01-29 18:49:01     at ammonite.util.Catching.flatMap(Res.scala:115)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.processSingleBlock(Interpreter.scala:328)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.$anonfun$processModule$8(Interpreter.scala:412)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.$anonfun$processAllScriptBlocks$3(Interpreter.scala:540)
2024-01-29 18:49:01     at ammonite.util.Res$Success.flatMap(Res.scala:62)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.compileRunBlock$1(Interpreter.scala:526)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.$anonfun$processAllScriptBlocks$15(Interpreter.scala:587)
2024-01-29 18:49:01     at ammonite.util.Res$Success.flatMap(Res.scala:62)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.$anonfun$processAllScriptBlocks$14(Interpreter.scala:584)
2024-01-29 18:49:01     at ammonite.util.Res$Success.flatMap(Res.scala:62)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.$anonfun$processAllScriptBlocks$12(Interpreter.scala:581)
2024-01-29 18:49:01     at scala.Option.getOrElse(Option.scala:201)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.loop$1(Interpreter.scala:581)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.processAllScriptBlocks(Interpreter.scala:619)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.$anonfun$processModule$6(Interpreter.scala:414)
2024-01-29 18:49:01     at ammonite.util.Catching.flatMap(Res.scala:115)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.$anonfun$processModule$5(Interpreter.scala:405)
2024-01-29 18:49:01     at ammonite.util.Res$Success.flatMap(Res.scala:62)
2024-01-29 18:49:01     at ammonite.interp.Interpreter.processModule(Interpreter.scala:395)
2024-01-29 18:49:01     at com.digitalasset.canton.console.HeadlessConsole$.com$digitalasset$canton$console$HeadlessConsole$$runCode(HeadlessConsole.scala:180)
2024-01-29 18:49:01     at com.digitalasset.canton.console.HeadlessConsole.$anonfun$runModule$2(HeadlessConsole.scala:71)
2024-01-29 18:49:01     at scala.util.Either.flatMap(Either.scala:352)
2024-01-29 18:49:01     at com.digitalasset.canton.console.HeadlessConsole.com$digitalasset$canton$console$HeadlessConsole$$runModule(HeadlessConsole.scala:68)
2024-01-29 18:49:01     at com.digitalasset.canton.console.HeadlessConsole$.$anonfun$run$1(HeadlessConsole.scala:124)
2024-01-29 18:49:01     at scala.util.Either.flatMap(Either.scala:352)
2024-01-29 18:49:01     at com.digitalasset.canton.console.HeadlessConsole$.run(HeadlessConsole.scala:123)
2024-01-29 18:49:01     at com.digitalasset.canton.ConsoleScriptRunner$.$anonfun$run$4(Runner.scala:180)
2024-01-29 18:49:01     at scala.util.Either.flatMap(Either.scala:352)
2024-01-29 18:49:01     at com.digitalasset.canton.ConsoleScriptRunner$.run(Runner.scala:171)
2024-01-29 18:49:01     at com.digitalasset.canton.ConsoleScriptRunner.run(Runner.scala:86)
2024-01-29 18:49:01     at com.digitalasset.canton.CantonAppDriver.delayedEndpoint$com$digitalasset$canton$CantonAppDriver$1(CantonAppDriver.scala:200)
2024-01-29 18:49:01     at com.digitalasset.canton.CantonAppDriver$delayedInit$body.apply(CantonAppDriver.scala:29)
2024-01-29 18:49:01     at scala.Function0.apply$mcV$sp(Function0.scala:42)
2024-01-29 18:49:01     at scala.Function0.apply$mcV$sp$(Function0.scala:42)
2024-01-29 18:49:01     at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
2024-01-29 18:49:01     at scala.App.$anonfun$main$1(App.scala:98)
2024-01-29 18:49:01     at scala.App.$anonfun$main$1$adapted(App.scala:98)
2024-01-29 18:49:01     at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:575)
2024-01-29 18:49:01     at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:573)
2024-01-29 18:49:01     at scala.collection.AbstractIterable.foreach(Iterable.scala:933)
2024-01-29 18:49:01     at scala.App.main(App.scala:98)
2024-01-29 18:49:01     at scala.App.main$(App.scala:96)
2024-01-29 18:49:01     at com.digitalasset.canton.CantonAppDriver.main(CantonAppDriver.scala:29)
2024-01-29 18:49:01     at com.digitalasset.canton.CantonEnterpriseApp.main(CantonEnterpriseApp.scala)
participant1.conf
canton {
  features.enable-preview-commands = yes
  participants {
    participant1 {
      storage.type = memory
      ledger-api.port = 5003
      ledger-api.address = participant1
      admin-api.port = 5004
      admin-api.address = participant1
    }
  }
}
docker-compose.yaml
services:

  mydomain:
    container_name: mydomain
    image: digitalasset-docker.jfrog.io/canton-enterprise:2.7.6
    volumes:
      - ./configs:/canton/host/configs:r
    command: daemon --config "/canton/host/configs/mydomain.conf" --log-profile container
    expose:
      - 5001
      - 5002
    ports:
      - 5001:5001
      - 5002:5002

  participant1:
    container_name: participant1
    image: digitalasset-docker.jfrog.io/canton-enterprise:2.7.6
    volumes:
      - ./configs:/canton/host/configs:r
      - ./.daml/dist/:/canton/host/dist/:r
    command: daemon --config "/canton/host/configs/participant1.conf" --bootstrap "/canton/host/configs/participant1.canton" --log-profile container
    depends_on:
      - mydomain
    expose:
      - 5003
      - 5004
    ports:
      - 5003:5003
      - 5004:5004

Question: What do I need to know and do to avoid this exception?

The participant must still be connected to the domain for step 1 of the migration process.

@b_heather, thank you!

Moving the disconnect(...) calls down addressed the “Cannot disable party…” error.

    // preparation
    val mrrp = mydomain.service.get_max_rate_per_participant
    mydomain.service.set_max_rate_per_participant(0)
    val gzipfile = "/canton/host/configs/alice.acs.gz"
    
    // migration
    logger.info("Beginning step one.")
    repair.party_migration.step1_hold_and_store_acs(
      alice, participant1, participant2.id, gzipfile)

    participant1.domains.disconnect("mydomain")
    participant2.domains.disconnect("mydomain")

              :
              :