`templatefile` evaluating `path.root` differently

I’m trying to generalize my local file paths so packer is less dependent on the calling path.

My directory structure is something like:

project
└── packer
    ├── cloud
    │   └── template.pkr.hcl
    ├── runtime
    │   ├── file1.txt
    │   └── file2.pkrtpl.hcl
    └── scripts
        └── myscript.sh

If I want to call: packer validate packer/cloud/ from the project root, I need to set the build block of my template.pkr.hcl to something like:

build {
  provisioner "file" {
    sources = [
      "${path.root}/../runtime/file1.txt"
    ]
    destination = "/tmp/"
  }
  provisioner "file" {
    content = templatefile("${path.root}/../../../runtime/file2.pkrtpl.hcl", {
      VARIABLE = var.my_variable
    })
    destination = "/tmp/file2.txt"
  }

  provisioner "shell" {
    scripts = [
      "${path.root}/../scripts/myscript.sh"
    ]
  }
}

And that works, but I don’t understand why templatefile requires a different path traversal than sources or scripts.

And if instead I want to call: packer validate . from the cloud directory, the above build block fails with no file exists at ../../../runtime/file2.pkrtpl.hcl. but the other stanzas work without issue.

The path.root variable seems kind of useless if it changes, and I couldn’t find any bug reports in GitHub, so I’m assuming I’m doing something wrong here… any help?