pkl icon indicating copy to clipboard operation
pkl copied to clipboard

Poor typecheck error message when using absolute package import for project dependency

Open StefMa opened this issue 1 month ago • 5 comments

[bioball] When using an absolute package import in place of a project import, Pkl eval will fail (expected). However, the error message thrown by Pkl is quite poor.

Original issue:


Given

PklProject:

amends "pkl:Project"

dependencies {
  ["pkl.impl.ghactions"] { uri = "package://pkg.pkl-lang.org/pkl-project-commons/[email protected]" }
  ["gha"] { uri = "package://pkg.pkl-lang.org/github.com/stefma/pkl-gha/[email protected]" }
}

index.pkl:

amends "@gha/Workflow.pkl"
import "ver/test.pkl"

name = "PKL IntelliJ CI"

on {
  public {}
}

jobs {
  ["a"] {
    name = "Placeholder"
    `runs-on` = "ubuntu-latest"
    steps {
      new {
        name = "Do nothing"
        run = "echo 'This is a placeholder job.'"
      }
      new test.Action {
        with {
          `java-version` = ""
        }
      }
    }
  }
}

ver/test.pkl:

import "package://pkg.pkl-lang.org/github.com/stefma/pkl-gha/[email protected]#/Workflow.pkl"

class Action extends Workflow.TypedStep {
  fixed uses = "actions/setup-java@v3"
  with: ActionInputs?
}

class ActionInputs {
  `java-version`: (String|Number|Boolean)?
}

[!CAUTION] Note the different imports. ver/test.pkl doesn't use @gha but the full package import.

When-Then

If I run pkl eval index.pkl then I get the following error

–– Pkl Error ––
Expected value of type `*Step|TypedStep`, but got type `test#Action`.
Value: new Action { name = ?; id = ?; `if` = ?; `timeout-minutes` = ?; env = ?; `wor...                                                                                                                                                                                                                                    

1019 | steps: Listing<*Step|TypedStep>
                      ^^^^^^^^^^^^^^^
at com.github.action.Workflow#DefaultJob.steps (projectpackage://pkg.pkl-lang.org/github.com/stefma/pkl-gha/[email protected]#/Workflow.pkl)

21 | new test.Action {
     ^^^^^^^^^^^^^^^^^
at index#jobs["a"].steps[#2] (file:///Users/stefan/Developer/pkl/pkl-intellij/.github/index.pkl, line 21)

128 | renderer.renderDocument(value)
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
at pkl.base#Module.output.text (https://github.com/apple/pkl/blob/0.30.0/stdlib/base.pkl#L128)

1318 | text = "# Do not modify!\n# This file was generated from a template using https://github.com/StefMa/pkl-gha\n\n\(super.text)"
                                                                                                                        ^^^^^^^^^^
at com.github.action.Workflow#output.text (projectpackage://pkg.pkl-lang.org/github.com/stefma/pkl-gha/[email protected]#/Workflow.pkl)

132 | if (renderer is BytesRenderer) renderer.renderDocument(value) else text.encodeToBytes("UTF-8")
                                                                         ^^^^
at pkl.base#Module.output.bytes (https://github.com/apple/pkl/blob/0.30.0/stdlib/base.pkl#L132)

Possible solution

Use the same import statement in both files! Either use @gha/ or package:// in index.pkl and ver/test.pkl

Observation

Even though the import is the same, pkl doesn't know that it is "valid". One pkl file uses the dependency notion (defined in PklProject), while the other uses the package import.

Expectation

I would expect that pkl can detect that using the @gha import is equal to the package:// import (for the same package obviously) and therefore don't error in such a import mix case.


Feel free to change the title of this issue. I've no idea how to call this 🫣

StefMa avatar Nov 12 '25 09:11 StefMa

This is expected; a project dependency is a different package than what you get with absolute package imports. If you're using dependencies, you cannot use import "package//:..." to satisfy the same types.

However, our error message is kind of bad here. I'm re-purposing your issue to be about the error message.

bioball avatar Nov 12 '25 16:11 bioball

But... 🤨 Why is it different? It is the same, right? So why are the types different?

Coming from outside, it looks like using a dependency notion is just like a "typealias". So I would expect that it work.

Also given your argument that "all" package:// import are different types, at least this is how I understand it, is not true. Because if I use it in both files, pkl detect that it is the same and it evaluate just fine...

StefMa avatar Nov 12 '25 17:11 StefMa

They're different because they resolve their own dependencies differently. A package:// import will resolve its dependencies according to its own manifest, whereas a dependency notation import will resolve dependencies according to the PklProject.deps.json file. Because of these, they can't be the same type.

By the way, a dependency notation import has scheme projectpackage:// underneath the hood, so they have different URIs!

bioball avatar Nov 12 '25 20:11 bioball

🤯 I chatted with AI a bit about this and it seems pkl distringuesh between the imports. So even if using the "same package", as soon as the import "looks" different (projectpackage (dependency notion), package (direct import), https (direct http import)), the types will never be the same. Correct?

So an http import of an pkl file that has package://stefma.github.acitons will not be compatible with the direct import or PklProject import within the project.

Understood. Thanks!

Indeed, a better error message should be thrown!

And btw: The intellij plugin also doesn't recognize this error! It isn't highlighed as an error.

Image

test.Action should be highlighted as "not compatible`.

StefMa avatar Nov 13 '25 07:11 StefMa

Yeah, agreed, that's an incorrect typecheck in pkl-intellij. Can you file an issue in apple/pkl-intellij? And likely we need to fix this for apple/pkl-lsp too.

bioball avatar Nov 13 '25 15:11 bioball