Hi there, this isn’t much of a question but more a clarification and maybe a request to add more info to the docs.
I have a workspace on Hub that I’ve been uploading my project to. The version for my project was 0.0.1 as all new daml apps are and I uploaded the dar file to Hub. Then I added more modules and templates to the app and uploaded the new dar file, still with version 0.0.1. I noticed that the new deployment was on a separate line under deployments and if I clicked into it, only showed the new modules/templates. Then I added more to the project (more modules and templates) and this time decided maybe I should bump the version to 0.0.2; I created the dar file and uploaded that now, so my workspace looks like this.
Is this behavior expected? Does all this make sense so far? Could you please explain a bit more how this all works (uploading multiple dars with same version 0.0.1, uploading dar with new version 0.0.2).
Next thing I noticed, after uploading version 0.0.2, was json-api requests that worked before now give this error:
After doing some digging, I believe this is because I now have two templates named Program:ProgramCommit on the same ledger (one in v0.0.1, one in v0.0.2) is that right? So if I wanted to uploaded 0.0.2 I should have made a new ledger? If so, is there a way to migrate data over to the new ledger?
Daml packages are ultimately identified by their Package ID, which is the only thing the ledger actually cares about. The package (/project) name and version are there for humans.
The Package ID of a package is a hash of the contents of the package. From you’re describing, it does seem very plausible that you have three different packages on the ledger at that point, as you have indeed pushed three different versions of your code.
The JSON API error is arguably bad UX on our part. When you interact with the Ledger API or the JSON API, you need to specify the Template ID of the template you want to use. A Template ID is formatted as
<Package ID>:<Module Name>.<Template Name>
You are not providing a Package ID for your template (which you can see because the first “segment” is None in the parsed representation in the error message). In that case, as a convenience for local development and CLI interactions using curl, the JSON API will make a best-guess effort to resolve a Template based just on Module Name and Template Name, but that only works if there is only one match.
In the situation where you have uploaded multiple versions of the same code, it is likely that you will end up with two (or three) packages with the same combination of Module Name and Template Name, and therefore the JSON API is no longer able to differentiate, and throws this error (rather than, say, picking a random one).
Note that not specifying the Package ID is not supported for production use. This behaviour is only there to support local debugging during development; you should never have any code that relies on it. Code should always use the full Template ID, including Package ID.
I’m not very familiar with the Hub UI, but locally you can get the Package ID of a DAR file by running daml damlc inspect-dar, for example:
$ daml new t
Created a new project in "t" based on the template "skeleton".
$ cd t
$ daml build
2022-09-09 14:52:00.48 [INFO] [build]
Compiling t to a DAR.
2022-09-09 14:52:01.43 [INFO] [build]
Created .daml/dist/t-0.0.1.dar
$ daml damlc inspect-dar .daml/dist/t-0.0.1.dar --json | jq -r .main_package_id
2126da5705ad370dee6b334b7d494bcf324db047daf20f20e55ee321faac7943
$
If you have a contract on ledger, you can identify the package ID for that contract’s template using the Live Data view. This is an example contract (taken from the Slack integration, but it doesn’t matter), as it’s displayed in Live Data:
The hex prefix in the templateID value is the package ID for that template. In this case, 214c1afa462fe133262f1854f5b989e7293cf4f3e24a6c259560dd790d082a27
(Note also that the status display for integrations allows the full package ID to be copied to the clipboard, for contract templates used in integration handlers event handlers. This is probably not applicable here, but can be useful.)