Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

kcl: PushKustomizeBase / Run cannot resolve KCL path deps pointing outside `source`

Open
#223 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
62/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
docker, go

Research direction

Start by locating Kcl.Run and the RenderKustomizeBase and PushKustomizeBase callers that mount /src and set the workdir. Add coverage under kcl/tests/ for the standalone path-dependency scenario, then verify the sub-package renders with a wider source and workdir while existing calls without workdir still work.

Written by the indexing model from the issue text.

Description

Summary

Kcl.Run (and therefore RenderKustomizeBase / PushKustomizeBase) mounts the caller-supplied source directory to /src and runs kcl run <entrypoint> with workdir /src. This works for self-contained KCL packages, but silently breaks any package whose kcl.mod has a local path = "..." dependency that lives outside source — the parent directory isn't mounted in the container, so kcl run fails to resolve the dep.

This bites the moment you try to share KCL code between sibling packages in a monorepo, which is a fairly common layout.

Motivating real-world example

In stuttgart-things/dapr-workflows we want a shared deploy-base KCL module at the repo root and per-workflow consumers that depend on it:

```
dapr-workflows/
├── deploy-base/ # shared KCL module
│ ├── kcl.mod
│ ├── worker.k
│ ├── statestore.k
│ ├── secrets.k
│ └── ca.k
└── backstage-template-execution/
└── deploy/
├── kcl.mod # depends on ../../deploy-base
└── main.k
```

`deploy/kcl.mod`:

```toml
[package]
name = "backstage-template-execution-deploy"
edition = "v0.11.0"
version = "0.1.0"

[dependencies]
k8s = "1.31.2"
deploy_base = { path = "../../deploy-base" }
```

Local `kcl run main.k` inside `deploy/` works fine (kcl walks up two dirs and finds `deploy-base/`).

The equivalent dagger call — as used by our Taskfile — fails:

```bash
dagger call -m github.com/stuttgart-things/dagger/kcl push-kustomize-base \
--source ./backstage-template-execution/deploy \
--address ghcr.io/stuttgart-things/backstage-template-execution-kustomize \
--tag v0.0.1 \
--user env:GITHUB_USER \
--password env:GITHUB_TOKEN
```

…because only `./backstage-template-execution/deploy` is mounted at `/src`. `../../deploy-base` resolves to `/deploy-base` inside the container, which doesn't exist.

Minimal repro (standalone test data)

```bash
mkdir -p /tmp/kcl-pathdep/shared /tmp/kcl-pathdep/consumer
cd /tmp/kcl-pathdep

cat > shared/kcl.mod <<'TOML'
[package]
name = "shared"
edition = "v0.11.0"
version = "0.1.0"
TOML

cat > shared/lib.k <<'KCL'
greet = lambda name: str -> str {
"hello, " + name
}
KCL

cat > consumer/kcl.mod <<'TOML'
[package]
name = "consumer"
edition = "v0.11.0"
version = "0.1.0"

[dependencies]
shared = { path = "../shared" }
TOML

cat > consumer/main.k <<'KCL'
import shared.lib as lib
message = lib.greet("dagger")
KCL

Works locally:

cd consumer && kcl run main.k

=> message: hello, dagger

Fails via dagger:

dagger call -m github.com/stuttgart-things/dagger/kcl run \
--source ./consumer

=> ERROR resolving dependency 'shared': path '../shared' does not exist

```

Expected behavior

Callers should have a way to let `Run` / `RenderKustomizeBase` / `PushKustomizeBase` mount a wider directory as the build context while still rendering a specific sub-package.

Proposed fix — option A (preferred)

Add a `workdir` (or `subpath`) parameter to `Run`. Callers pass the repo root as `source` and a sub-path as `workdir`:

```go
func (m *Kcl) Run(
ctx context.Context,
source *dagger.Directory,
// +optional
ociSource string,
// Sub-path inside source to cd into before running kcl. Enables
// KCL packages with relative path deps pointing outside their own
// directory (e.g. shared modules in a monorepo).
// +optional
workdir string,
// ... rest unchanged
) (*dagger.File, error) {
// ...
if source != nil {
ctr = ctr.WithMountedDirectory("/src", source)
if workdir != "" {
ctr = ctr.WithWorkdir("/src/" + workdir)
} else {
ctr = ctr.WithWorkdir("/src")
}
}
// ...
}
```

Then `RenderKustomizeBase` and `PushKustomizeBase` forward the same new parameter. Usage becomes:

```bash
dagger call -m github.com/stuttgart-things/dagger/kcl push-kustomize-base \
--source . \
--workdir backstage-template-execution/deploy \
--address ghcr.io/stuttgart-things/backstage-template-execution-kustomize \
--tag v0.0.1 \
--user env:GITHUB_USER \
--password env:GITHUB_TOKEN
```

Backwards compatible — omit `--workdir` and behavior is identical to today.

Proposed fix — option B

Add a separate `contextDir` parameter that mounts at `/src` alongside the existing `source` which continues to point at the entrypoint package. Slightly uglier API (two directories, two mount points) but also backwards compatible.

Acceptance criteria

  • The minimal standalone repro above renders successfully via `dagger call run --source . --workdir consumer`
  • `PushKustomizeBase` accepts the same `workdir` and produces a kustomize base from the sub-package
  • Existing callers (no `workdir` set) continue to work unchanged
  • A test is added under `kcl/tests/` that exercises a path-dep sub-package

Workarounds until this lands

  1. Publish the shared module as an OCI KCL package (`kcl mod push oci://...`) and switch the dep from `path = "..."` to `oci = "..."`. Adds a publish step and a chicken-and-egg on first push.
  2. Vendor/symlink the shared module into each consumer's `deploy/` before calling dagger. Brittle and loses single-source-of-truth.
Dominant language
Go
Stars
4
Forks
0
Avg merge
21h 53m
Merged PRs (30d)
26

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from stuttgart-things/dagger

All issues in stuttgart-things/dagger

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.