#github-feed

1 messages · Page 21 of 1

ornate vigilBOT
#

@IljaKroonen have you tried copying the files into dagger from the host, with pre-call filtering to only copy what you need? I understand that the entire NFS mounts are surely too large to copy, but how much data do you actually need to copy into dagger? Depending on the answer you may not need a new feature at all, and may be able to get a solid implementation with pre-call filtering.

#

@jpadams the reason why this happens is because WithoutEntrypoint removes both the entrypoint and default args (https://github.com/dagger/dagger/blob/main/core/schema/container.go#L993-L995) unless KeepDefaultsArgs is set. This has been like this for a while and is not related to the change introduced in #9305 so pre v0.15.0 pipelines will also get an error by stating that the container command has not been set.

Going back to your examples, because the second example calls `Witho...

#

just needing to use shell.

What does "needing to use shell" entail? In the model we currently use, Jenkins invokes a single dagger function (using dagger call) and passes in the git repository and auth. What would this look like if we also wanted to make a directory available under your proposal?

Basically, the dagger shell supports explicitly passing the output of one function as argument to another, using the familiar subcommand syntax of the bash syntax. For example:

dagger ...
ornate vigilBOT
#

Bikeshedding the API design for new volume constructors (I think we should implement it regardless, unlike secret providers where we'll have to retrofit - do you agree?)

Yeah I want there to be APIs for each volume type, if that's what you're getting at (sshfsVolume, nfsVolume, etc.)

Deciding on adding a convenience URI format now vs. later

Really no strong opinion on this. I feel like it can be safely saved until it's desired by anyone. In the meantime invoking from shell or an ...

#

Local dev docs can be found here, but will outline some more pointers specific to this effort.

cc @IljaKroonen and team

Implementation

Will give a high-level outline here, obviously happy to fill in details as needed.

API schema

We'll want a new Volume type and associated Query.sshfsVolume API for creating one.

  • This is fairly boilerplate-y, can follow patterns in the core/ and core/schema/ packages
  • e.g. us...
#

having the ability to mount FFS shares in dagger would solve our problem but I don't think this is practical to implement. The environment in which we run won't allow us to mount directly using the Linux NFS driver and while a fuse implementation exists, I am not sure how reliable it is

Ah okay, good to know. I'm guessing it gets into something deeply specific to your setup, but if you are able to share why it doesn't work I'd be curious to know. I did a quick hacky test with my own NFS se...

#
  1. The sshfs ideally shouldn't be container-based API. The reason is that pulling a large filesystem and unmounting before running the next container can be expensive compared to mounting the filesystem once, sharing that directory between containers, and unmounting. However, it does go against the proposed design.

I don't follow. It would be perfectly fine for the engine to mount the sshfs once and then share that mount by just bind mounting it into each container that needs it. Whe...

#

I can confirm that Nikola's patch is working for our use case.

You can see it here: https://github.com/G-Research/dagger/tree/nikola-jokic/sshfs-volume

Both these methods in there are suitable for us:

  • dag.SshfsVolume successfully connects to our host and allows accessing the files from WithExec
  • the WithMountedHostDirectory also achieves what we want pretty much directly but my understand from the above that we would like to avoid exposing this kind of primitive (I think the name cou...
ornate vigilBOT
ornate vigilBOT
#

This proposal is for a variation of the design prototyped in #8730. It started as a comment in that PR, which I'm formalizing here.

Overview

In #8730 we introduce the concept of secret providers: an expansion of Dagger's ability to load secrets, with 1password integration as the reference implementation of a provider. This makes the user experience better, by making Dagger itself smarter and less dependent on lon...

#

What is the issue?

The daggermod folder is mounted such that only root can write to it. If a container is returned that has .WithUser("not-root"), introspection/invocation will fail.

Dagger version

v0.15.2

Steps to reproduce

Check out https://github.com/M-Pixel/dagger/tree/m-pixel-csharp

Remove .WithUser("0") from /sdk/dotnet/module/main.go

From the dotnet directory, run dagger init --sdk=../module test; dagger call -m test default-cow

Or re-create the scenario on...

ornate vigilBOT
#

This would make it easier to handle differences between APIs and capabilities between secret providers. The downside as I see it is that code will be more tied to a specific secret provider. A use case I've thought a lot about is local flows using a password-manager style provider like 1password, while CI environments would use a proper secret provider like Vault. When the URI is untyped this is pretty easy. Maybe this isn't a use case we're trying to solve for yet.

#

Also having this issue when I'm trying to mount a cache volume to a redis container

func (m *MyModule) Redis() *dagger.Container {
  return dag.
     Container().
     From("bitnami/redis").
     WithExposedPort(6379)
     WithMountedCache("/bitnami/redis/data", dag.CacheVolume("redis-cache")
}

This will fail:

dagger call redis up

14:M 23 Jan 2025 16:00:10.566 # Can't open or create append-only dir appendonlydir: Permission denied 

To fix that I need to manually se...

ornate vigilBOT
#

Problem

Dagger SDKs do not bundle 100% of their code and dependencies. This means that when a developer builds their module, their build downloads third party packages from various third-party registries. And, because Dagger doesn't have a distinct build phase, this happens at runtime.

As a result, it's difficult to run Dagger modules behind corporate proxies, or in airgapped environments. There is ongoing work to allow configuring various proxies, but it's a game of whack-a-mole.

...

ornate vigilBOT
#

I've tried few things to bundle the TypeScript SDK and that's promising.

I'm using bun bundler to bundle the TypeScript library and tsc to emit type declaration.

So we end up with a directory of only 2 files: index.js and index.d.ts.
It's working fine but that requires to rebundle on every runs which is something we want to avoid so here's another solution that fix the proble:

  1. When buil...
ornate vigilBOT
#

What are you trying to do?

It takes roughly 2 to 3 minutes for me to install private modules and then have it execute the functions.
It would be great if I can create custom dagger engine with some of the private modules pre-installed and then run this engine in our CI (gitlab cicd).

Why is this important to you?

It will save us time.

How are you currently working around this?

No response

ornate vigilBOT
#

What is the issue?

Contrary to the docs, which states that mounted directories are included, Container.directory() does not include mounted directories when listing entries or calling export on a parent directory.

Our use case is to include log files from a mounted build directory when errors or warnings occur, in order to export them to the CI runner context. We scan the build log to extract absolute...

ornate vigilBOT
#

What is the issue?

If declare a function that returns a list of type ([]*T, []*dagger.Container for example), the Go codegen will render as []T instead of []*T that look break the convention.

Dagger version

dagger v0.15.3 (registry.dagger.io/engine:v0.15.3) darwin/arm64

Steps to reproduce

Create a module that has a function like this example below:

func (m *KptBuilder) Build(source *dagger.Directory) (ctrs []*dagger.Container) {
	// ...
}

Then, create a n...

#

Module version compatibility was introduced originally in https://github.com/dagger/dagger/issues/7640. Essentially, it allows modules to be served a compatible old API, while we're free to modernize the API for new + updated modules.

However, the original really only covers changes to fields:

We don't handle changes to types - I remem...

#

What are you trying to do?

Passing arrays to Dagger functions via the CLI is currently done with comma separation. What if I'm passing a string that needs to include a comma? What if I'm passing an array of arrays? I found that \ doesn't escape commas (if it did, it would probably be bad for some Windows users).

I'm not suggesting that JSON array syntax should be the only option. But if an array input begins with [, it should be treated as a JSON array. Google's GN is an ex...

#

What Happens

This works as expected:

#[DaggerObject]
class MyModule
{
    #[DaggerFunction]
    public function returnSelf(): MyModule
    {
        return $this;
    }
}

However, this fails:

#[DaggerObject]
class MyModule
{
    #[DaggerFunction]
    public function returnSelf(): self
    {
        return $this;
    }
}

What A PHP Developer Might Expect

Both examples to work identically.

Solution

I'm not sure of all the intricacies of self as a return ...

ornate vigilBOT
#

Module version compatibility was introduced originally in https://github.com/dagger/dagger/issues/7640. When it was originally added, we decided that we would only add Views for fields that changed or removed - added fields wouldn't get a field.

That's because, there's actually no need from a compatibility point-of-view.

The main reason that we might want to is that it's technically possible right now to dagger develop --compat to a specific ``, and get a view of the API that is c...

#

This started flaking occasionally a few days ago. First occurrence I found is at https://v3.dagger.cloud/dagger/traces/99b8612ffeb0bd86a718c0d3164e0ffb?span=c7b32ffabfbd2e59

Error looks like

failed to check if module already exists: input: moduleSource failed to stat local path: failed to stat path: failed to get requester session: session for "1s13ivxachyz418qvzs4dtfoh" not found

It's a bit of a mystery since the TestSystemCACert tests run against their own isolated nested engine...

#

What are you trying to do?

If I'm instrumenting my tests with custom spans, I'd like to be able to x-reference those spans based on git metadata so my initiated-from-main CI runs are distinguishable from my intiated-from-branch CI runs. CI Infra engineers responsible for pipeline maintenance are often looking to understand how long each test case takes to run across different environments and versions, as well as how often they suceed or fail to determine test flakiness. [Datadog has som...

ornate vigilBOT
#

Saw this happen one time so far: https://v3.dagger.cloud/dagger/traces/cdca068a2bc3f4a24669294d6d55b6a2?span=9bb360c22dab5941&logs

time="2025-04-19T01:42:46Z" level=debug msg="merging edges" dest_index=2 dest_vertex_digest="sha256:25054e2b8aa9a0a72570be4927725d143b9efc775b097111ab630993fc648079" dest_vertex_name="npm pkg set type=module" source_edge_index=2 source_edge_vertex_digest="sha256:8e05840352c710528a008aaf070ad90ea1c78ac5b3ae04d2ae04736a0e93df6b" source_edge_vertex_name="npm pkg...
ornate vigilBOT
#

What is the issue?

When doing this command :

dagger call build-env --source=.

with :


 @function
    def build_env(self, source: dagger.Directory) -> dagger.Container:
        """Build a ready-to-use development environment"""
        python_cache = dag.cache_volume("python")
        return (
            dag.container()
            .from_("127.0.0.1:5000/pythonflask")
            .with_directory("/var/flaskapp/", source)
            .with_mounted_cache("/var/flaskapp...
ornate vigilBOT
#

Problem

Coming from: https://discord.com/channels/707636530424053791/1342430286331379712

Given the following pipeline:

func main() {

    ctx := context.Background()
    d := dag.Host().Directory(".")

    dc := d.Directory("contracts")

    dag.Container().From("ubuntu").
        WithMountedDirectory("/workdir", d).
        WithMountedDirectory("/workdir/contracts", dc).
        WithExec([]string{"apt", "update", "-y"}).Sync(ctx)
}

with the following file structure:

...
ornate vigilBOT
#

When installing the official Dagger helm chart following the docs here https://docs.dagger.io/ci/integrations/kubernetes/#example, the resulting volume paths seem to contain the dagger word a bit too much:

        serviceAccountName: default
        terminationGracePeriodSeconds: 300
        volumes:
        - hostPath:
            path: /var/lib/dagger-dagger-dagger-helm
            type: ""
          name: varlibdagger
        - hostPath:
            path: /run/dagger-dagger-dagger...
ornate vigilBOT
#

What are you trying to do?

It would be nice to support environment variables to configure aspects of the CLI. Specifically things like --progress without requiring those to be set each time call run is invoked.

Some examples from the CLI reference page:

  1. --debug would be DAGGER_DEBUG=true
  2. --progress would be DAGGER_PROGRESS=plain
  3. --silent would be DAGGER_SILENT=true
  4. etc ...

Related Discord: https://discord.com/chann...

ornate vigilBOT
#

TL;DR

This issue describes the MagicSDK project and aim to gather opinions and feedbacks from the community.
The goal is simple: make it possible to adopt Dagger in a project without writing code on day one.

Description

Adopting Dagger requires some investment, you need to learn the concept of module, how to create your own with SDKs, use the published on Daggerverse etc.. it's a big learning curve and even if the rewards are great after adoption, it's still a lot.

The goal is t...

ornate vigilBOT
#

What is the issue?

Right now if the engine is not ready by the time the CLI tries to connect it shows a scary looking error in dagger cloud.

connection error: desc = "error reading server preface: command [docker exec -i dagger-engine-v0.15.1 buildctl dial-stdio] has exited with exit status 1, make sure the URL is valid, and Docker 18.09 or later is installed on the remote host: stderr=Error: dial unix /run/buildkit/buildkitd.sock: connect: no such file or directory\nUsage:\n  dial...
#

Overview

In the context of a new LLM type, it would be amazing if we could send token count as otel metrics, the same way we already send cpu, memory and IO metrics.

Design considerations

The design is still TBD. But it seems feasible.

Per @sipsma on Discord:

sgtm, the current metrics only come from exec-ops but the underlying infra will work in any other api call I believe.

to sketch out what you'd need to do the equivalent of using current code as an example:

  • [...
ornate vigilBOT
#

In [a discord discussion](#maintainers message), @vito said:

i'm not sure if we have it already, but we could define a generic ID type, and the function could decode it to determine the type at runtime

[...] we would need to handle it (generic objects) at the SDK layer somehow, e.g. for ID args that should probably translate to an interface implemented by all objects in Go (prob the XXX_GraphQLID thingy we have already)

#

What are you trying to do?

It is possible to write some dagger code like:

func (m *MyModule) doLotsOfStuff() {
    baseContainer := dag.Container();

    parallelBuilds = []*dagger.Container{
        baseContainer.WithExec([]string{"do", "stuff", "a"}),
        baseContainer.WithExec([]string{"do", "stuff", "b"}),
        baseContainer.WithExec([]string{"do", "stuff", "c"}),
        baseContainer.WithExec([]string{"do", "stuff", "d"}),
        baseContainer.WithExec([]string{"do", ...
#

We should revive the work in https://github.com/dagger/dagger/pull/8201 (was closed due to lack of time, but it's quite useful in our new SDK interface world that's being worked on by @TomChv as part of https://github.com/dagger/dagger/issues/9582).

This would help fix:

  • #6621
  • #7834
  • #7707

It also feels heavily linked to #10480 #7707, and would help decouple init and develop more.

This new Init method would be in a new Init interface in core/sdk.go, something like:

ornate vigilBOT
#

What is the issue?

You cannot have a function name in a module that is named Query

Dagger version

dagger v0.17.0-llm.11 (docker-image://registry.dagger.io/engine:v0.17.0-llm.11) darwin/arm64

Steps to reproduce

When defining a module with the function Query the dagger develop will complete fine, but running dagger functions you get the following error:

# dagger/database-agent/internal/dagger
internal/dagger/dagger.gen.go:7977:2: query redeclared
        internal/d...
#

I think something like that could do the job

defmodule MyModule do
use Dagger.Mod.Object, name: "MyModule"

defmodule Severity do
use Dagger.Mod.Enum

 defenum [
  # Undetermined risk; analyze further
  UNKNOWN: "UKNOWN",
  # Minimal risk; routine fix
  LOW: "LOW",
  # Moderate risk; timely fix
  MEDIUM: "MEDIUM",
  # Serious risk; quick fix needed.
  HIGH: "HIGH",
  # Severe risk; immediate action.
  C...
ornate vigilBOT
ornate vigilBOT
ornate vigilBOT
#

What is the issue?

Update:
https://docs.dagger.io/faq#what-is-the-dagger-platform - mention our expanded agents and CI use cases
https://docs.dagger.io/faq#dagger-sdks - mention all of the SDKs

Add:
in an entry similar to https://docs.dagger.io/faq#which-ci-providers-does-dagger-cloud-work-with, describe which LLMs and frameworks we work with. Short answer is that Dagger should work with any hosted or local LLM. With Dagger's multi-language support and ability to use any libraries or c...

ornate vigilBOT
ornate vigilBOT
ornate vigilBOT
#

What are you trying to do?

Using the Directory built in object is a bit clumsy; I'd like to create a function which iterates through the files/directories in a provided Directory argument. While it is possible to do using the entries() function; this returns an array of strings which isn't easy to work with.

I propose adding a files() function and a directories() function which would return an array of File objects for each file in the dir, or an array of Directory objects for each dir...

#

What is the issue?

Disk hit 100% and I was unable to clean it with dagger commands like prune. I think this is because it's trying to spin up a module?

Use "dagger [command] --help" for more information about a command.
/ # dagger core
✔ connect 0.1s
✘ loading type definitions 0.1s
! query module objects: input: failed to get schema: failed to select introspection JSON file: select: parent snapshot z62ntc4rcflkf4lixwzv8hk2b does not exist: not found

Dagger version

16.1
...

ornate vigilBOT
#

What are you trying to do?

I want to use my host's configured Git credentials within containers in Dagger.

Why is this important to you?

I want to be able to git fetch additional branches to what is already checked out within a git context. This is important for tools like SonarQube where it requires the context of the reference branch to do the analysis. There may be other use cases which require a fetch/pull from remote when working with current git directories. This is easy t...

#

Problem

When configuring Goose to use dagger mcp as an extension, the extension fails to load with a cryptic error. It turns out that the default log output of dagger mcp is interpreted as an error, or invalid output, by Goose. Calling dagger -s mcp instead solves it. This is confusing and should not be the default outcome.

Solution

Make it so that dagger mcp works as a Goose extension / MCP server, without having to guess which flags to add.

ornate vigilBOT
#

What is the issue?

Pardon my laziness, I will copy-paste from discord

I tried setting up dagger engine behind a k8s service (and tried to configure dagger client to connect to the dagger engine using k8s service name + port). While the connection is established, dagger builds fail with some weird error saying smth about an invalid session. I straced dagger and saw that it opens x4 connections to the dagger engine. Since k8s services are load-balanced round-robin, each connection was pro...

#

In the context of client generation and various discussion with @shykes and @helderco.
We conclude that the introspectionJSON arg in SDK module should not be required since they are other ways to get a module object definition (with the typedefAPI).

So I opened a PR (https://github.com/dagger/dagger/pull/9778) to expose the introspectionJSON file with an API call, so it’s up to the SDK maintainer to use it or not.
In #9778, the introspectionJSON API query is part of moduleSource but it...

ornate vigilBOT
#

What is the issue?

I opened this issue as the project lacks proper documentation around how to setup a dev environment for the project. I was trying to contribute to this project but unfortunately, after first PR is merged, I am unable to move forward. I tried a lot to setup a local running engine that I can debug via dlv, and failed.

A dev documentation exists, however I feel that this document expects developer to already know about the project. This is the one: https://github.com/...

ornate vigilBOT
#

What is the issue?

When passing an uninitialized object to a method, it gives a 400 GraphQL error without a clear error message of what went wrong.

Code:

@object()
export class TSProject implements Project {
    source: Directory
    ctr: Container
    packageCache: CacheVolume;
    buildCache: CacheVolume;
    readonly projectDir = "/app/";
    constructor(
        @argument()
        source: Directory
    ) {
        this.source = source;
        this.ctr = dag.node().withPnpm()...
#

What are you trying to do?

When returning a custom type, or even a slice of strings. It would be great to have a native json method. Given this example return type: https://github.com/jasonmccallister/sql/blob/e1267aa57b6a46f8dd2f31aa9507c3e6584281a4/main.go#L16

In order to see the values of the fields, you would need to pipe | multiple times. Instead, if the return type supported a json chain - it would be human readable.

Note: bonus points for additional types like `csv...

ornate vigilBOT
ornate vigilBOT
ornate vigilBOT
ornate vigilBOT
ornate vigilBOT
#

What happened? What did you expect to happen?

I'm new to dagger and trying to figure out some odd behavior.

I have a Dagger module that calls an API endpoint to create something, when the module calls the API endpoint directly like so:

package main

func (r *MyModule) CreateSomething(ctx context.Context, token *dagger.Secret, environment, version string) (string, error) {
	apiClient, err := api.NewClient(ctx, token, environment)
	if err != nil {
		return "", fmt.Errorf("create cl...
#

What is the issue?

I don't know if the Rust SDK was meant to be cross compatible (Unix & Windows) but it would be useful to allow the SDK be able to compile in Windows by separating the following configuration below referenced for Unix and Windows.

The issue is that the dagger-sdk crate is attempting to use Unix-specific functionality (os::unix::prelude::PermissionsExt and set_mode on Permissions) on a Windows platform. This won't work because the unix module within os is c...

#

What are you trying to do?

Many users have requested the ability to capture the state of a Container that has been modified through an interactive session with terminal such as in

⋈   container | from alpine | terminal

dagger / $   apk add git
dagger / $   exit
✔ container | from alpine | terminal 3m47s
Container@xxh3:0991463b40bf15ca

It would be amazing if you could just run

⋈   ctr=$_
⋈  $ctr

Why is this important to you?

No response

How are ...

ornate vigilBOT
#

What are you trying to do?

If there is an issue with a specific model, it would be great to be able to fall back to a different model. For example I sometimes get rate limited or stuck with the following errors:

│🤖 1.7s
│ ! received error while streaming:
│ ! {"type":"error","error":{"details":null,"type":"overloaded_error","message":"Overloaded"}}
! input: llm.withQuery.withPrompt.sync select: received error while streaming:
! {"type":"error","error":{"details":null,"type":"overlo...
ornate vigilBOT
#

What are you trying to do?

Currently we are using dagger for our build workflow.

One of the steps in this flow is that we are doing a docker build using the context:
baseContainer.build(context);
What we noticed is that there is a bit of a difference between the error output that we expect to see in local docker builds and dagger builds.

E.g.: forcing a build failure by making an instruction in the Dockerfile cause a failure

docker


  => [5/8] RUN apt-get install -y git gc...
#

Problem

Visual Studio Code has extensions to show CI status directly in the editor. This is done with extensions, such as the Github Actions extension. Unfortunately the same integration is not available with Dagger Cloud. Even if my CI is configured to run Dagger, and send telemetry to Dagger Cloud, I cannot access the status of my Dagger pipelines as conveniently.

Solution

Implement a Visual Studio Code extension which integrates directly with Dagger Cloud, and shows CI status dir...

ornate vigilBOT
#

ref: #agents message

When the engine fails to start using the docker driver, it currently requires some manual docker logs troubleshooting to understand what's happening. We can simplify troubleshooting if we fetch the logs ourselves and print them through stdout.

Here's an example of what users generally get:

connection error: desc = "error reading server preface: command [docker exec -i dagger-engine-v0.18.5 ...
ornate vigilBOT
#

What is the issue?

Hopefully, this is not a duplicate bug report, i couldn't find one. Happy to close if its already a known issue.

Dagger shell behaviour with files (and directories?) is not the same. Seems like a bug as relative is working on WSL, but its not possible to make it work on Windows, because the directory system is different, so you cannot relative path to the file, if the module/shell is on a separate drive e.g D:\ compared to a file being passed to it.

https://github....

#

What are you trying to do?

Access a module's own version information directly from within the module, without requiring expensive git tag fetching operations. See this conversation in discord: #maintainers message.

Specifically, we'd like the github.com/dagger/dagger/version module to be more efficient by enabling a pattern like dag.CurrentModule().Version() which would return the current version (tag or commit SHA) ...

ornate vigilBOT
#

Shell and call do work differently. Shell is sandboxed by your module’s context directory (unless you’ve started with -M), which is either your git repository root or your module’s root if not in a git repo. It works similarly to default paths, but where relative paths are resolved relative to the current working directory within the shell session, which is the module’s root directory initially by default.

For example, assuming your module is in ...

#

Sections in the Dagger blog are not linkable. This is annoying since some of our blog posts have a lot of rich content that we often want to reference later. For example, release announcements. Instead of linking to a particular feature in the announcement, I have to link to the whole post and say "scroll down to the part about ".

ornate vigilBOT
#

What is the issue?

To improve performance for long-running tests, I want to export cache volumes into container images, store them in a registry, and restore them on the next run. While writing these functions, I noticed strange behavior with cache volumes. I already know that changes to cache volume contents don't invalidate the engine's cache, and the current solution is to invalidate the cache using a random variable. However, I dis...

ornate vigilBOT
#

Problem

The default verbosity of the TUI is awesome, but... it's a lot. People get overwhelmed - like running shell scripts with set -x by default. Or stracing your unix tools by default.

This is actually 2 problems in 1:

  • Problem 1: the default verbosity is too high
  • Problem 2: the lower verbosity, as implemented, is still overwhelming. We need a different kind of low-verbosity output

Solution

Default output should be a new output, with a fixed depth of 2. Basically, only ...

ornate vigilBOT
#

Description

Whenever there is an update to Dagger and it needs to pull the newest Dagger engine image, the process gets through most of the download but then exits with an unexpected EOF. This issue is temporarily resolved by performing a docker pull of the new image manually.

Environment

  • Operating System: NixOS
  • Installation Method: dagger/nix flake

Logs

95010d052422: Pulling fs layer
b16238853797: Pulling fs layer
d0d32b261184: Pulling fs layer
failed to copy...
#

Currently, Dagger provides excellent built-in observability for its own pipeline execution using OpenTelemetry (OTel), visualized beautifully in the TUI and Dagger Cloud.

Separately, Deno now offers native, built-in OpenTelemetry support (--unstable-otel, OTEL_DENO=true), allowing Deno applications to emit traces, metrics, and logs using the OTLP standard (Deno OTel Docs).

When running a Deno application that uses this native...

ornate vigilBOT
#

What is the issue?

Installing the helm chart using fluxcd fails as the version number gets rendered differently

This appears to happen with a few apps (though dagger is in this thread)
Flux seems to render the version with a Sha

So it fails with

  Failed to apply default image tag "registry.dagger.io/engine:v0.18.5+bbb202ea8932": couldn't parse image name "registry.dagger.io/engine:v0.18.5+bbb202ea8932": invalid reference format

It appears AppVersion is preferred over Versi...

ornate vigilBOT
#

🤔 I'm guessing this is because the chart version is being set to v0.18.5+bbb202ea8932 somehow?

We use the chart version to set the image to pull, see: https://github.com/dagger/dagger/blob/800a91e04595cda22533f1051e8645d4417a01a9/helm/dagger/templates/engine-statefulset.yaml#L67-L69

You can override the image using engine.image.ref as a workaround, but honestly, it seems a bit weird that the version set here isn't an actual tagged release of the chart - those aren't really supported (th...

ornate vigilBOT
#

What is the issue?

A project with a number in the name, such as "k8s-test-app", causes class lookup failure with Python SDK.

No @dagger.object_type decorated class named K8sTestApp was found

I tried various combinations of dagger init --name k8s-test-app and renaming generated python module directory and class name. Also tried using [project.entry-points."dagger.mod"] in pyproject.toml but only managed to produce different kinds of lookup errors.

Would it be possible to con...

#

Is your feature request related to a problem? Please describe.

Currently, there isn't a dedicated, step-by-step guide in the official Dagger documentation detailing how to configure Dagger's OpenTelemetry (OTEL) trace exporting to send data to Grafana Cloud for visualization. Users have to piece together information from OTEL documentation, Grafana Cloud documentation, and potentially community examples, which can be time-consuming and error-prone.

Describe the solution you'd like

...

ornate vigilBOT
#

What is the issue?

I followed

Setup tracing at https://dagger.cloud/traces/setup. To hide set DAGGER_NO_NAG=1

from the CLI.
It was working yesterday, so I believe it's a token expiration thing.
So I got to the traces setup page, clicked on the github logo
Then, I saw the loading page of dagger cloud v3, but nothing loaded and the request log showed me this

POST	https://auth.dagger.cloud/oauth/token

403
{"error":"invalid_grant","error_description":"Invalid authorization co...
ornate vigilBOT
#

Currently Dagger routes LLM requests to the appropriate client based on model names https://github.com/dagger/dagger/blob/main/core/llm.go#L285

This is not scalable to hosted providers (azure, aws bedrock, google vertex) or proxies (litellm, gpustack, ...) because you generally have a single OpenAI compatible service hosting all of your models.

Dagger should have an explicit provider option that overrides the automatic routing to support these services

ornate vigilBOT
#

Motivation:
Integrate support for running WebAssembly (WASM) workloads via Docker's WASM integration (e.g., using the wasi/wasm platform) within Dagger pipelines. This would allow users to leverage the benefits of WASM for specific pipeline steps or services.

Benefits of WASM:
Adding WASM support offers significant advantages for future DevOps, production, and deployment scenarios:

  • Performance & Efficiency: WASM modules have near-native execution speed and incredibly fast ...
#

What is the issue?

Dagger clients do not properly detect session termination and continue executing even after a shutdown is triggered, resulting in the job running until a full CI timeout.

In our case, healthchecks were failing fatally in the background and the session was closed, but the client continued running .withExec() steps and exporting files, unaware of the termination. This caused the job to appear stuck without any progress updates, eventually failing only after hitting...

ornate vigilBOT
#

What is the issue?

When running this function:

    @function
    def lib_deps(self) -> dagger.Directory:
        base_dir = dag.container().from_("debian:bookworm-slim").directory("/usr/lib")      
        libs = (dag.container()
            .from_("debian:bookworm-slim")
            .with_exec(["apt", "update"])      
            .with_exec(["apt-get", "install", "-y", "zlib1g"])
            .directory("/usr/lib")
        )

        return libs.diff(base_dir)

I face

...
ornate vigilBOT
#

What are you trying to do?

The typical use case is running database migrations against a database service, with the goal of running a container using the resulting, migrated / seeded database.

Right now, there is nothing to chain from to get the modified directories on the service.

Example API that could solve this:

  @function
  def database_service(self, src: Source) -> dagger.Service:
      postgres = dag.container().from_("postgres:latest").with_env_variable("POSTGRES_P...
#

What is the issue?

The engine connection process is being interrupted, resulting in multiple connection errors. The specific error message "error reading server preface: read |0: file already closed" showing while trying to connect dagger engine. Please refer the attached screenshot.

Image

Dagger version

dagger v0.18.9 (docker-image://registry.dagger.io/engine:v0.18.9) windows/amd64

Steps to r...

ornate vigilBOT
#

What is the issue?

shamelessly copy-pasting from [discord](#general message):

in dagger 0.18.6, while exitting a container container | from node:18-alpine | with-mounted-directory /mnt ./ | terminal back into dagger shell, I woke up some hungry ass beast sleeping inside Dagger that immediatelly ate up all the remaining 14G of my RAM.

Yes, I'm calling it -- there's a memleak somewhere in there 🙂 killing dagger proce...

#

What are you trying to do?

We would like to run commands in containers and use the output as the value of a secret

Doing it naively appears to be insecure and ends up logging password.txt. Snippet with a source available example

	plaintext, err := m.AwsSdk().
		WithEnvVariable("AWS_ACCESS_KEY_ID", roleCredentials.AccessKey).
		WithSecretVariable("AWS_SECRET_ACCESS_KEY", roleCredentials.SecretKey).
		WithSecretVariable("AWS_SECURITY_TOKEN", roleCredentials.SecurityToken).
		WithExec...
ornate vigilBOT
#

Had a quick discussion with @marcosnils - we both decided we don't like the above - it feels dangerous that you can read a Secret from any file, which would be cached. So, Container.secret will need to have a check to ensure that the secret file has been "masked" correctly using WithSecretVariable.

Using Container.withMountedSecret to mask that path is also kind of weird, since it requires that you first call setSecret with an empty value. Instead of that, we could have `Container....

#

Problem

Current Dagger pipelines lack a built-in, seamless, and secure method for handling sensitive information like API keys and database credentials across various execution environments. This complicates secure secret management and degrades the developer experience.

Solution

Propose adding a robust, built-in secret management service to Dagger Cloud. This service would provide:

  • Centralized storage for diverse secret types.
  • Version control for secrets, enabling easy rotation an...
ornate vigilBOT
#

What are you trying to do?

Right now, it shows when it was executed, but I believe it would also be nice to see how long it has taken.
Especially if you chain runs on your CI (as I did) and want to compare 2 runs.

Why is this important to you?

As I passed from 5m30s with empty cache from depot.dev to 44s with hot cache, it's very compelling to see the improvement.

How are you currently working around this?

Clicking on each run to see the difference

#

What is the issue?

If I run the following command time dagger --cloud -m github.com/dagger/dagger call check --targets=docs from my $HOME directory, the command fails and it takes ~30s total: https://dagger.cloud/gerhard/traces/120a91f99d41d8d5c0623d896c38e7b4#0f4fdcf4884dc83c

If I run the same command from cd $(mktemp -d) it succeeds & it finished within ~20s: https://dagger.cloud/gerhard/traces/36412a610d902cadb6fa2214ce376d6d#276b326231fc59cc

It seems that when I run t...

ornate vigilBOT
#

What are you trying to do?

imagePullSecrets (https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) could be taken advantage of by dagger, mainly considering one can easily hit dockerhub pull limits.

Currently there's a workaround that can be done, by explicitly mounting the ~/.docker/config.json into the k8s pod where the dagger CLI runs.
However, if this could be integrated with a more "native k8s way", that would simplify a lot the life of dagger u...

#

What happened? What did you expect to happen?

I'am using docker buildx bake to use multi-step build.

In docker buildx I can use target as base image like below

In dockerfile

FROM base_image

# .. some docker step

In bakefile reference

target "intermediate" {
   ...
}

target "output" {
   dockerfile = "./Dockerfile.out"
   contexts = {
     base_image = "target:intermediate" 
   }
}

Then, target output build docker image based on build result of target intermediate

I...

ornate vigilBOT
#

What are you trying to do?

GitHub Models is a very convenient LLM provider that available in-context in GitHub Actions via GITHUB_TOKEN.

It's also easily available from any context where you're logged in with gh.

This makes it extremely convenient for LLMs involving software engineering, e.g. in GitHub Actions.

Could we please add GitHub Models as an implemented and documented model provider?

Thank you

Why is this important to you?

...

#

What is the issue?

When using Dagger in gitlab-ci the pipeline succeeds even if the steps fail.

For example we push the alpine container to a registry. It returns success even if it fail to push the container.

Dagger version

dagger v0.18.9 (docker-image://registry.dagger.io/engine:v0.18.9) linux/amd64

Steps to reproduce

  1. Deploy a Kubernetes Executor
  2. Create a dagger pipeline to push an image to private registry.
  3. call the pipeline in gitlab ci without specifying the ...
ornate vigilBOT
#

What are you trying to do?

I would like to have a container that can talk with a service it depends on, such that they can call up each other:

flowchart LR
    a[Container] -->|dials| b[Service]
    b -->|dials| a

In practice, the Go code looks something like:

svc := docker.Container().From(...).AsService(...)
c := docker.Container().From(...)

// There is no way to make them communicate between one another at this stage!
c, err := c.Sync(ctx)

Why is this...

ornate vigilBOT
#

What is the issue?

Given the following code:

type Test struct {
	Test string
}

func (m *Dagger) Test(test Test) {}

Running test test in the Dagger interactive shell results in:

✘ test test 0.0s ERROR
! query:
  query{dagger{test(test:"test")}}

  error: parse selections: parse field "test": init arg "test" value as core.DynamicID (DaggerTestID!) using core.DynamicID: decode "DaggerTest" ID: failed to unmarshal proto: proto: cannot parse invalid wire-
  format data
```...
ornate vigilBOT
#

What is the issue?

When testing out Dagger locally, layers seemed to fail to cache randomly. It was confusing to me because it seemed like Dagger caching wasn't working at all as advertised. I was running Dagger under a Colima VM on my mac with a virtual disk size of 25GB.

I pruned my Dagger cache (and some other caches on that VM) and restarted the test, and suddenly things were caching as expected! It was then when I checked the Dagger caching documentation and saw the note about Dagg...

ornate vigilBOT
#

To prevent users from being confused in the future, Dagger should warn them if a cache GC prevented their layer from otherwise being loaded from cache. I'm not sure the best way to do this, maybe a "tombstone" when a layer is deleted from a cache with that layer's inputs? And then some sort of warning on the CLI when a layer could've been restored from cache but wasn't able to be because a tombstone was present?

Good idea. We're coincidentally working and revamping some of the caching int...

#

What are you trying to do?

Hello,

In our setup, we have created our own JSON config file that controls a lot of the moving parts in the pipeline (software versions, toggleable options, etc.). The config file is a module input of type *dagger.File, and it gets read and unmarshalled at the start of the pipeline. This makes it so that the entire pipeline depends on the digest of the entire file. If we so much as just change a whitespace character in the file, the entire chain gets cache-...

ornate vigilBOT
#

What are you trying to do?

Currently, the Java SDK is not usable in Enterprise use cases (maybe even non-enterprise) because it doesn't support user local .m2/settings.xml. This settings.xml is where the user sets private registry as well as auth. It's similar to the auth file docker stores on local and dagger pull that in automatically. Same happens with Git for private registries. This solution may require somethings similar.

Why is this important to you?

Java is probably o...

ornate vigilBOT
#

What are you trying to do?

I have multiple modules that are using models. Some modules are using the same model, some are using others.
I'm defining the module in a .env file in each module directory, but there's some limitations:

  • what if I'd like to use two models running in different places? For instance I'd like to use a local model running on my machine and gpt, both inside the same dagger module.
  • how can I share configuration across multiple modules? I need to copy/paste my `...
ornate vigilBOT
#

What are you trying to do?

I would like to be able check if image:tag already exists in remote repository i.e. I want a wanted dagger.Container.Exists function to check if the container/tag are available, similar to how dagger.Container.Publish is today.

It would be nice to be able to do this using 'Container' for several use cases, currently my options are (I guess) ...

Option Supported in Dagger Credentials Handled Complexity Best For
Container().Publi...
ornate vigilBOT
#

I've found it's technically possible to do this by calling Sync and checking the returned error. For example,

package main

import (
	"context"
)

type ImageExists struct{}

func (m *ImageExists) Exists(ctx context.Context, ref string) string {
	_, err := dag.Container().From(ref).Sync(ctx)
	if err != nil {
		return "does not exist"
	}
	return "image exists"
}

And calling

$ dagger call exists --ref does-not-exist
▶ connect 0.5s
▶ load module: . 5.9s
● parsing command line...
#

What are you trying to do?

It would be a really helpful feature to support telemetry for dagger.Service types.

Why is this important to you?

Adding telemetry support to dagger.Service would help developers with debugging applications. Capturing metrics like HTTP request methods, URIs, response times, and status codes would allow developers to troubleshoot performance issues locally, and in cloud, such as identifying slow endpoints.

How are you currently working around this?...

ornate vigilBOT
#

This was discussed on Discord [here](#general message).

A quick and dirty example:

main.go

package main

import (
	"dagger/dagger-test/pkg/foo"
)

type DaggerTest struct{}

// Foo returns a custom Foo type
func (m *DaggerTest) Foo() *foo.Foo {
	return foo.NewFoo(dag)
}

pkg/foo/foo.go

package foo

import (
	"dagger/dagger-test/internal/dagger"
)

// Foo is a simple custom Dagger type
type Foo struct {
	//...
#

Currently written in the documentation: "Only types and functions in the top-level package are part of the public-facing API for the module."

Would be nice if external sources such as e.g. go modules were supported for type definition.


Let us assume the following content in a go example module:

type Example struct {
	foo     string
	bar  string
}

Once published it could be added to dagger modules with go sdk like:

go get example.com/example/ex@v0.0.0

The s...

ornate vigilBOT
#

Current behavior:

I have an engine running that is version v0.18.9
I have just upgraded my CLI to version v0.18.10

Default behavior:

When I run something with the CLI, like dagger functions, the CLI will kill the v0.18.9 engine, start up a v0.18.10 engine, connect to it, and run my command

Leave old engine

If I set DAGGER_LEAVE_OLD_ENGINE=1 in my environment first, the CLI will start a new v0.18.10 engine for my session, but it will not delete the v0.18.9 e...

ornate vigilBOT
#

What are you trying to do?

Environments are a way to define a specific set of functions an LLM will be able to see as tools. This allows to reduce the number of tools the LLM will see or to provide specific tools, both in order to improve the ability to complete a task.

[!NOTE]
This is extracted from #8030 but focusing only the LLM/Env/type awareness and not on the self calling aspects.

It's currently possible to use a primitive type a...

ornate vigilBOT
#

Let's say I have a module my-agent that contains a type workspace (a struct in Go, a class in Java, etc).

What I want is:

dag.Env().WithWorkspaceInput("input", &Workspace{}, "the workspace")

Type Exposure

By default the Workspace type is not exposed. It needs to be exposed by a function of the module to be exposed. So it needs somethings like that:

func (m *MyAgent) Workspace() *Workspace { return &Workspace{} }

Then we can imagine to keep the above cal...

#

@eunomie The dag.Self().Workspace() approach (or dag.MyModule().Workspace() per https://github.com/dagger/dagger/issues/10336#issuecomment-2855190339) makes the most sense to me, at a technical level.

The problem with directly passing a &Workspace{} is that all object arguments work by passing the object's ID, which is generated through the process of making API calls. If you directly create a &Workspace{} and pass it in, we don't have an easy way to translate that to an ID at the AP...

#

All right, I have a first PoC ~working. I'll open a draft PR with it. It's just a PoC, there's multiple issues and improvements required:

  • drop in speed
  • codegen doesn't work in all cases (but module call works)
  • the display of the conversation with the model disappeared
  • this currently only works with the java SDK and it requires changes on the SDK side

But I'm able to run my previous demo with the workspace within the main module, so without ...

#

@eunomie I don't have the complete answer, but wanted to make a more general note on self-calls: if possible, I think we should avoid dag.Self() and instead use dag.Foo() where foo is the name of the module. In other words, the naming of the binding should be the same as for regular dependencies.

I think there are several reasons for this. But one specific reason for me, is that I want to leave the door open to having more than one runtime per module in the future ("runtime stacking") ...

#

As I understand it, the current proposal would look like this in Go:

func (m *HelloDagger) Agent(ctx context.Context, prompt string) (string, error) {
    ws := dag.HelloDagger().Workspace()
    return dag.LLM().
        WithHelloDaggerWorkspaceInput(ws).
        WithPrompt(prompt).
        LastReply(ctx)
}

func (m *HelloDagger) Workspace() *Workspace {
    return &Workspace{
        ctr: dag.Container().From("alpine"),
    }
}

type Workspace struct {
    ctr *dagger.Container
}

fun...
ornate vigilBOT
ornate vigilBOT
#

Problem

Suppose a user is working on a fairly standard frontend/backend project. The user will likely have two separate Services for each service:

func (MyModule) Frontend(
    // +defaultPath="./src/frontend"
    src *dagger.Directory,
) *dagger.Service {
    return dag.Container().
        From("node:latest").
        WithWorkdir("/src").
        WithMountedDirectory(".", src).
        WithExec([]string{"npm", "install"}).
        WithExec([]string{"npm", "build"}).
        Wit...
ornate vigilBOT
#
#

I was trying to load a different version of the trivy module, and it conflicted with the local one. I was hoping the session destroy and mod cache prune commands would clear the cache, and I could get the intended version of trivy. This is the error I was trying to work around:

! failed to serve module: module trivy (source: github.com/jpadams/daggerverse/trivy@44c178290a412483e785a436aabc46c707842a62 | pin:
44c178290a412483e785a436aabc46c707842a62) already exists with different sou...
#

For svc.Endpoint, it would work identically to how it already works today for a multi-port service. Not sure if there's a specific issue here.

The new service group would probably have to get a new hostname specifically for that. Then, svc.Hostname would make sense? Sadly, that does mean that under the hood we'll probably have to proxy.

WithServiceBinding would bind all the ports in the service to the specified hostname - just like it does today.

This makes me think if it might b...

ornate vigilBOT
ornate vigilBOT
ornate vigilBOT
#

What are you trying to do?

I would like to inspect the host where the CLI is running to understand where exactly the dagger engine is running. As an Enterprise user of dagger, we have various compliance and security needs that we need to meet. One such need is the need to know exactly where the client (and the engine) is running.

We would like to take actions within our modules based on the host.

Why is this important to you?

An example of something we would like to do is, based ...

#

https://docs.dagger.io/api/chaining#export-directories-files-and-containers
https://github.com/dagger/dagger/blame/14ff07af8b91c091e1f1e7afbf0e01316142f8ca/docs/current_docs/api/chaining.mdx#L217-L219

▼ github.com/kpenfound/dagger-modules/golang@v0.2.1 |
  build ./cmd/dagger --source=https://github.com/dagger/dagger |
  export ./my-build 0.0s ERROR r jump ↴
╰─✘ export 0.0s ERROR r jump ↴
  ! input: golang.build failed to stat file /out: process "go build -o /out/ ./cmd/dagger" did not co...
ornate vigilBOT
#

Following this discussion: #1384134172502659162 message

Summary

Private package authentication in Dagger requires different approaches across SDKs. All SDKs can use git-based packages via SSH authentication, but many enterprises require HTTPS with Personal Access Tokens instead. Additionally, Python and TypeScript have package registries (PyPI, npm) that need separate authentication. Regarding the current private registry support...

#

A second failing example in the same section:

▼ github.com/dagger/dagger/modules/ruff |
  lint https://github.com/dagger/dagger |
  report |
  export /tmp/report.json 24.6s ERROR r jump ↴
╰─✘ export 9.0s ERROR r jump ↴
  ! ghcr.io/astral-sh/ruff:0.11.13@sha256:45cb2b28f0ad694917b159c65d058f1eeafdda0cb155a30374194c4c4b6c56df: failed to resolve source metadata
    for ghcr.io/astral-sh/ruff:0.11.13@sha256:45cb2b28f0ad694917b159c65d058f1eeafdda0cb155a30374194c4c4b6c56df: failed to authorize:...
#

I don't think this is something we're likely to add.

We would like to take actions within our modules based on the host.

The way to do this should be through function arguments - there's no other mechanism we're really looking at to do that.

One of the reasons for this is that function arguments are explicit - you can cache a function based on it's arguments. But if that function inspects other information, then that's suddenly not possible - all of the caching we can currently do (and...

#

The way to do this should be through function arguments - there's no other mechanism we're really looking at to do that.

The problem with function arguments is that they are user provided. Which won't work with what I'm trying to do as they can be spoofed.

Fair. The way I'd accomplish this is with properly scoped credentials - users shouldn't have credentials able to push to that remote registry. I'm not sure that dagger specifically should provide this logic.

Also fair. Let's say, ins...

#

An example of something we would like to do is, based on whether the user ran dagger from their local laptop or in Jenkins CI, we would like to prevent certain actions like publishing artifacts to our artifact registry.

This as an argument of "exposing host details about where the CLI is running" doesn't seem that strong to me.

First, because I agree with Justin that this should probably be enforced at a different level given that enforcing this in Dagger doesn't prevent the fact that us...

#

Python requires embedding credentials in URLs (not the best security practice) while TypeScript has no registry auth support.

Are you sure about this?

AFAIK npm supports npm login so you could use that to login to any registry service (i.e: https://jfrog.com/help/r/jfrog-artifactory-documentation/authenticate-using-npm-login). And AFAIK python has the .pipyrc config file where you can specify your repositories and credentials (https://packaging.python.org/en/latest/specifications/p...

ornate vigilBOT
#

What are you trying to do?

I am trying to reliably access (both programmatically and in Dagger Cloud) the output of .with_exec() steps that might or might not have been cached previously. Right now it seems cached steps don't store their stdout, so cached and non-cached runs behave differently.

Related Discord thread: https://discord.com/channels/707636530424053791/1397564686618198026

Why is this important to you?

Generally speaking, caching is a technique to improve performanc...

#

What is the issue?

I have a module which creates a symlink over a file which already exists. I've been using a small helper function to call ln -sf to create the symlink, but decided to move to using the WithSymlink introduced recently. Understandably, calling it raises the following error:

! symlink /dev/stdout /var/lib/dagger/worker/cachemounts/buildkit3966597304/var/log/nginx/access.log: file exists

I don't necessarily expect the default behaviour to override the file, b...

ornate vigilBOT
#

Not related to the implementation discussion above, but still possibly relevant ([source](#1397564686618198026 message)):

Once [the present ticket] gets implemented, I suppose this would impact the behavior of stdout()? Namely, its presence/absence wouldn't really make a difference anymore [for the TUI], since the output of all commands would always be available and shown by dagger run -v. However, I only want to show [on the c...

ornate vigilBOT
#

cc @alexcb

We're actually already very inconsistent with how we handle overwriting existing content.

  • Creating a file with WithNewFile on top of an existing file, succeeds
    • container | with-new-file "foo" "" | with-new-file "foo" ""
  • Creating a directory with WithDirectory on top of an existing file, succeeds
    • container | with-new-file "foo" "" | with-directory "foo" $(directory)
  • Creating a file with WithNewFile on top of an existing directory, fails
    • `container | wi...
#

Agreed we should do this :tada: (or at least have a dial to make it configurable).

The reason that it doesn't do this today is because the OTEL terminal output is created inside the WithExec dagop, which doesn't run if cached. https://github.com/dagger/dagger/blob/b8fd58b689a0ea2e3159f8bf2ac3d0e3fc7ab6ad/engine/buildkit/executor_spec.go#L659-L662

I think it's possible to create this same kind of span if we're cached (I think we can detect this case), and simply read the stdout file from...

#

@jedevc Ideally it'd be even more detailed: the telemetry log data is split between stdout and stderr streams, and it'd be nice if we preserved all that on cache hits too. That way logs will be interleaved like they were when it really ran, and if we want to do UI cues for stdout vs. stderr (e.g. stderr slightly red background) we can have it for cache hits too.

Maybe we could somehow align telemetry with caching? Like when we cache an op, we also keep its related telemetry? Right now that a...

#

We added support for module interfaces a while back.

However, we never went the full way and we didn't ever need interfaces in the "core" module (the main dagger API). So it just doesn't work right now.

There are several cases I think we should support:

  • Allowing core types to implement core-defined interfaces
    • Some types just make more sense as an interface! They already have multiple "backends", like GitRepository or Service. We should expose this implied interface as a real int...
ornate vigilBOT
#

It may be possible now to use Copilot APIs as an LLM provider allowing users with Copilot access to use those models within Dagger.

Looking at the implementation in sst/opencode, we should be able to initiate an oauth flow with Copilot. There are some references to using a token as well which may or may not actually work. Needs investigation.

With token (may not work):
Set base_url to https://api.githubcopilot.com
Get the api key from ~/.config/github-copilot/apps.json

Oauth flow:
http...

ornate vigilBOT
#

What happened? What did you expect to happen?

Hi there. I created this issue to document how a recent change to the engine impacted us when upgrading. We have since solved our issue, but I thought it might be interesting to document it here.

Our organisation deploys a single version of the dagger engine for our CI runners - this is because it would be too expensive to deploy multiple versions. Dagger modules across repos are subject to the CI version and when upgrading, all CI builds ar...

ornate vigilBOT
#

It's not a TUI issue. But it's also not an intentional optimization/simplification.

Here's what's happening - when you make these calls, they both end up with the same content digest:

  • Host.directory(path: "/", exclude: ["something-that-doesnt-exist"])
  • Host.directory(path: "/")

I changed a module to have two context dirs like this, and was able to reproduce the problem:

  • Trace 1 - when the ignored file doesn't ex...
ornate vigilBOT
#

Maybe we could allow "pinning" to a semver spec as an alternative to a precise SHA, and always roll forward to the latest compatible? Then, at least, you can signal breaking changes with a major version bump.

This would be ideal. I agree with OP and can definitely relate.
If you were rolling out blueprints across multiple repos, you’d absolutely want the option to pin to a major or minor blueprint version.

#

What are you trying to do?

User asked:

Another question on this .... is a --source that is a git repo a full clone? Am I supposed to have access to all the tag and metadata?

Short answer, no.

since i'm working with azure repos it complicates things. Good to know i explored all options. made it a little tricky 🙂

You can look at
/a case:

dagger -M -c 'container | from alpine/git | with-workdir /a | \
with-exec git,clone,https://github.com/dagger/dagger,. | terminal'

vs
`/b...

#

Setup

Assume the following module:

package main

import (
	"context"
	"dagger/foo/internal/dagger"
)

type Foo struct {
	Entries []string
}

func New(
	ctx context.Context,
	// description goes here
	// +defaultPath="./arg"
	// +ignore=["foo.txt"]
	myArg *dagger.Directory,
) (*Foo, error) {
	entries, err := myArg.Entries(ctx)
	if err != nil {
		return nil, err
	}
	return &Foo{entries}, nil
}

With the following testdata:

$ mkdir arg
$ touch arg/{foo,bar}.txt

Get the t...

ornate vigilBOT
#

What are you trying to do?

I am currently building an experimental Continuous Delivery (CD) pipeline using Dagger to release software & configuration changes to our CDN platform. This requires taking multiple inputs, such as the details of the person making the change, the artefacts to release (packages & versions, configuration changes) and the list of targets (physical machines) to deploy the changes onto. This input data must be validated, and is stored beyond the lifetime of the Dagg...

#

Today, the functions and their args do not illustrate some common best practices and style.
The large comment block is simply removed by most and so we should make it much shorter and to the point.
Fixing this will help adoption and be a more delightful experience for new and existing users.

  • [ ] module comments shortened to essential
  • [ ] functions/args reworked
  • [ ] tests updated (there are many tests relying on the output of dagger init today)
ornate vigilBOT
#

What is the issue?

Description
I'm deploying Dagger as a DaemonSet on a Kubernetes cluster, and I've set CPU and memory limits on the dagger-engine pods. However, the containers launched by Dagger (dagger core container from ...) do not inherit these resource constraints, and can consume significantly more memory than specified.

Dagger version

dagger v0.18.12 (unix:///run/dagger/engine.sock) linux/amd64

Steps to reproduce

Setup

  • Dagger version: v0.18.12
    -...
ornate vigilBOT
#

Additional investigation on cgroups for containers launched by Dagger

I ran a container inside Dagger and inspected its cgroup settings from within the container.
Here’s the result when inspecting /sys/fs/cgroup/

/ # ls /sys/fs/cgroup/buildkit/<containerID>/
cgroup.controllers        cgroup.max.descendants    cgroup.type               cpu.stat                  cpuset.cpus.partition     ... [truncated for brevity]
/ # cat /sys/fs/cgroup/buildkit/<containerID>/cpu.max
max 100000...
ornate vigilBOT
#

Pretty much this:

https://github.com/dagger/dagger/blob/40dba8d312c76caed679a9ba952048c52c96a259/core/git.go#L789-L794

Problems:

  • Bad caching. If a submodule A is already in the cache as repo A, we won't actually clone after that.
  • Weird auth. See https://github.com/dagger/dagger/pull/10855#discussion_r2266427963. We should be able to configure auth for submodules.
  • Inflexible. While we can configure the --depth of a clone, we can't do this for submodules - we always go to ...
ornate vigilBOT
#

@shykes under that suggestion, is there a way to distinguish between the live service mounts or the live service rebuild?

I think if there's a way to do that, I don't have a huge objection - I do think it'll make implementation trickier (especially in terms of what can/can't cache), which is one of the reasons I preferred a separate type - I'll have to give it a proper think to see if I can understand the implications.

I'd also want to make sure that every type can support a watch metho...

#

Ok, I've updated the top-level with a new proposal that keeps existing types and doesn't introduce any. It's not quite as discussed, but I think it's neat!

The big changes from the discussion we've had is:

  • Service.watch isn't a thing - instead, I've put it as an argument to AsService.
    1. Service.watch only really makes sense on container services, it kind of breaks the service abstraction.
    2. It's really useful (implementation wise) to know at the time of service creation whether...
#

What is the issue?

Specifying $HOME environment variable in some Container.With* method does not expand the environment variable to what it's pointing to, despite the environment variable being defined in the container.

Is this a bug or is there something I am misunderstanding?

I am working around this by just writing out the path to $HOME, so it's not the end of the world, but it's an annoyance.

Dagger version

dagger v0.18.14 (docker-image://registry.dagger.io/engine:v0.18...

#

Some services (like the containerd service) only listen on unix sockets. We don't really support those, all our services are tcp/udp networked.

[!NOTE]

To workaround, we're doing something like: https://github.com/dagger/dagger/blob/28043bb7c21924d5e0663abf6ef3a2b8e8591f6c/core/integration/provision_test.go#L337-L344

We put the unix socket into a CacheVolume, and then mount it in both the server and the client.

This "works", but 1. is hacky, and 2. doesn't support useful feat...

#

It seems like after a terminal has been run in the "background" of the TUI, we fail to restore events correctly.

This seems to affect:

ornate vigilBOT
#

What is the issue?

Originally reported in discord: https://discord.com/channels/707636530424053791/1410361079061807306

I have a pipeline that after calling many functions reaches the point below. I find that the first terminal is not the same as the second one through --interactive when integration tests fail:

test_container = (frontend_with_env
                  .with_service_binding('proxy', proxy_service)
                  .with_service_binding('backend', back...
ornate vigilBOT
#

What is the issue?

As I saw in one of the previous releases, Dagger is now by default filtering files from .gitignore.

This erroneously affects files that are already added staged (for ex with git add --force, or added prior to .gitignore modifications), but would have fallen under .gitignore if they wouldn't.

I have a few small .mp4 files checked into the repo for testing purposes. My .gitignore also ignores **/.mp4. My tests in Dagger now started failing after an upgra...

ornate vigilBOT
#
#

What are you trying to do?

Building images, we get a lot of failures due to 429s from Docker Hub. Running with higher verbosity, it appears like there is a huge amount of simultaneous pull-requests being sent - including for images where we already have the latest version.

Mitigations that come to mind:

  1. Add CLI-flag to configure pull-behavior (always=like now, missing=only pull missing images, never=never attempt to pull base images from remote)
  2. Reduce number of simultaneous...
ornate vigilBOT
#

What is the issue?

Environment
• GKE cluster
• Self-hosted GitLab Runners
• Dagger Engine v0.18.15 deployed as DaemonSet on runner nodes

Problem

We’ve recently started seeing random pipeline failures with the error:

Dagger version

dagger v0.18.15 helm chart as a daemon-set

Steps to reproduce

Not sure how to produce it

Log output

When the error occurs, engine logs show thread exhaustion:

2025-09-11T04:50:39.601124906Z stderr F time="2025-09-11T04:50:39Z" lev...
#

#10867 added support for interactively debugging Directorys, Containers and Services.

However, one important thing is still missing: I can't debug an ExecErr.

For example:

I can't interactively debug the failed withExec - because it simply attempts to replay the ID, which fails.

Realistically, in this case, we should be able to replay the ExecErr, and enter that debug state - all without needing to pass -i at the top-level.

Doing this is a bit tricky - it means we'll need...

#

What is the issue?

Version 0.18.17 introduced the NoGitAutoIgnore argument, which is even highlighted in the releases as a breaking feature. Which with the rust sdk specifically means code no longer compiles without changes, which is not a good thing considering unless locked to a specific version cargo will happily update to newer patch versions.

Honestly I get that the change isnt too breaking for most of the sdks, due to optional arguments etc, but for rust which doesnt have tha...

ornate vigilBOT
#

Dagger has native 1password integration. To test it in dev, I need to inject a 1password service account token into the dev container. I do this manually eg. dev | with-secret-variable OP_SERVICE_ACCOUNT TOKEN xxx | ..., but it would be nice to make it an optional argument of dev and other build functions. Especially with upcoming #11034 , then I can add it to my .env and type shorter commands :)

#

What is the issue?

🚨 Dagger SDK Compatibility Issue with Go 1.24+ and 1.25.1

We've identified a critical compatibility issue when using Dagger SDK with Go 1.24+ and Go 1.25.1.

❌ Problem

Build fails with telemetry-related errors:

# dagger.io/dagger/telemetry
../../../go/pkg/mod/dagger.io/dagger@v0.18.17/telemetry/transform.go:69:29: cannot use res (variable of type *resource.Resource) as resource.Resource value in argument to ResourceToPB

🧪 Testing Results

| Go V...

ornate vigilBOT
#

Occasionally (several times a day), when exiting an interactive TUI session, dagger does not relinquish control back to my system shell: it just hangs there.

Anecdotically, this seems to happen after "big" interactive sessions, with a big build (dagger -m github.com/dagger/dagger | dev | ... | terminal...

#

What are you trying to do?

I'd like to use the Google Vertex APIs with Dagger. The Vertex APIs are different from Google's Gemini APIs in that they use the Application Default Credentials instead of a specific API key. The google.golang.org/genai package already being used in llm_google.go supports the Vertex APIs and a standard env var mechanism to inject them:

type ClientConfig struct {
	// Optional. API Key for GenAI. Required for BackendGeminiAPI.
	// Can also be set via t...
#

See https://github.com/dagger/dagger/pull/11073, https://github.com/dagger/dagger/pull/11032#issuecomment-3303982431

Essentially, we never really had a consistent behavior here - now everything at least pulls the tag history.

But it's not fully consistent:

  • doFetch should be set if we need to rework the tag history
  • The resulting fetch should still be set to a consistent view of the tag history (from the ls-remote we did earlier)
    • Even if tags got updated between resolution and fet...
#
#!/usr/bin/env python3
"""Simple test of Dagger container terminal functionality."""

import sys
import dagger


async def main():
    """Run a container with terminal access."""
    async with dagger.Connection() as client:
        container = (
            client.container()
            .from_("ubuntu:latest")
            .with_exec(["apt-get", "update"])
            .with_exec(["apt-get", "install", "-y", "bash"])
        )

        print("Starting terminal session in Ubuntu container....
#

What is the issue?

In v0.19.1, when both +defaultPath and +ignore evaluate to an empty directory, dagger incorrectly passes the source of a random dependent module instead.

Dagger version

dagger v0.19.1 (image://registry.dagger.io/engine:v0.19.1) darwin/arm64/v8

Steps to reproduce

Run https://github.com/skycaptain/dagger-issue-defaultPath with v0.19.0 and v0.19.1 and watch output.

$ dagger version
dagger v0.19.0 (image://registry.dagger.io/engine:v0.19.0) darwin/arm6...
#

What is the issue?

Given the following sample project:

-- main.go --
package main

import (
	"context"
	"dagger/socket/internal/dagger"
)

type Sockettest struct {
}

func (t *Sockettest) ReproduceSocketError(ctx context.Context, socket *dagger.Socket) error {
	repo := dag.Git("git@github.com:dagger/dagger-test-modules.git", dagger.GitOpts{
		SSHAuthSocket: socket,
	})
	root, _ := repo.Branch("main").Tree(dagger.GitRefTreeOpts{
		DiscardGitDir: true,
	}).Sync(ctx)

	_, err := dag.R...
ornate vigilBOT
#

Problem

When calling Changeset.asPatch, the full contents of the patch is dumped to the TUI, making the output unnecessarily verbose.

When chaining it with File.contents (Changeset.asPatch().contents()) that gets dumped too, so it's double penalty.

Solution

I guess change the logging and/or TUI rendering behavior, to not dump the full contents in Changeset.asPatch, and maybe File.contents while we're at it?

#

What is the issue?

System

  • Python SDK (dagger-io==0.18.16)
  • Matching Dagger Engine of 0.18.16

Description

I would like to exit my CI/CD pipeline early (or re-try) in the case that asService does not exit appropriately. I would assume there would be an exit_code() method exposed, similar to that of a Container object. However, this appears to not be the case.

The suggestion made in [this discord discussion,](https://discord.com/channels/707636530424053791/14262454389...

#

Dagger can natively load .gitignore and apply its rules to filter host directories pre-upload.

This feature is disabled by default, and can be enabled as an argument to Host.directory().
But, it can NOT be enabled by a function to specify pre-call filtering on its own arguments...
In other words, we are missing +gitignore (or +ignore="git")

Perhaps this is easier to implement by piggypacking on an existing directive (+ignore) which is already supported by all SDKs? But will SDKs allow p...

ornate vigilBOT
#

Problem

Currently the PHP SDK is synchronous only.

Technical Details

PHP (as of 8.4) has no standard way to perform asynchronous calls.

PHP has Fibers which get you part of the way there. But working purely with those is a bit awkward and there are already several libraries that wrap this step in a neat bow for you. 🎀

The GraphQL library we are using, can integrate with [several librari...

#

When I'm exploring modules, especially modules with multiple functions, this can take a while to understand what are the available functions to call.

It could be interesting to have an interactive way to browse functions.

Let's take as an example the main module of dagger/dagger:

$ dagger functions
▶ connect 0.5s
▶ load module: . 35.3s

Name              Description
bench             Find benchmark suites to run
bump              -
check-generated   Verify that generated code ...
ornate vigilBOT
#

What are you trying to do?

Right now every time you do a dagger develop the dagger.json just pins to your current engine version - even if it's a dev version.

This gets really annoying because half the time the module would be just fine on the version it was. It would be nice if we only bumped that version when the module actually needs it.

Maybe we could do that based on views? I don't think we're marking what version new APIs appear in, because there's a chicken-egg problem (don'...

#

Problem

Dagger takes a long time to load modules. As a result, every interaction with dagger starts with... waiting.
This makes the Dagger experience less delightful than it should be.

Solution

Find the lowest-hanging fruit for improving module load time, and pick it.
Rinse, repeat, until users spontaneously say "hey, Dagger feels much faster!"

#

What are you trying to do?

I’m trying to specify Vault secret paths in Dagger in a way that includes the secrets engine directly in the URL, such as:

vault:///.

Currently, Dagger requires a split configuration model where part of the path (the secrets engine mount) is defined in VAULT_PATH_PREFIX, and the remaining sub-path is written inside the secret reference (e.g., vault://PATH/TO/SECRET.FIELD).
I want to be able to specify the full Vault path—including the secrets engin...

ornate vigilBOT
#

About adding a new path scheme for backward compatibility: it seems to me that it would be more convenient to support just one scheme so the user doesn’t get confused. But we need agreement from at least a few contributors, and especially from @kpenfound , that this is okay and that development in this direction makes sense.

As for backward compatibility, we can try to preserve it like this: keep the VAULT_PATH_PREFIX variable working, and if it is set, simply prepend its value to the path...

ornate vigilBOT
#

What is the issue?

Sometimes the engine stops working with error messages like this:

Error: failed to load cache key: no active session for ja13ul8z8qvjxt376vmkvzvvs: context deadline exceeded

Looking at the engine logs, I've noticed two things:

1 - The first appearance of the error message always occurs after the same other log message:

time="2025-10-24T05:36:55Z" level=debug msg="checked for cached auth handler namespace" cached=true key="docker.io/library/node::pull" n...
ornate vigilBOT
ornate vigilBOT
#

Problem

We continuously publish dev builds from the main branch of Dagger, as usable releases. But the publishing process is slightly different, which requires special cases in the build scripts, and even in the CLI code.

Solution

Change how we publish nightly builds, to be more like stable releases. This will allow simplifying the release toolchain, and the CLI code. It will also remove complicated coupling between the two, thus making the whole system simpler.

Specifically:

-...

#

What is the issue?

When I run a Dagger function from the Python REPL or from the command-line, it makes changes to the terminal that are not cleaned up afterwards.

When I run from the terminal, it shows the animated log output, then after the function has finished running, it says “Disconnecting” and terminates. It fails to print a newline, and for some reason the blinking cursor disappears from my terminal session.

When I run from the Python REPL, the “Disconnecting” message with ...

ornate vigilBOT
ornate vigilBOT
#

Problem

When running dagger call from a local module, filesync operations (Host.directory()) are triggered by loading modules, loading contextual directories... These filesync operations are "orphaned": they don't appear as children of a top-level span. Combined with the fact that they are hidden by default... the result is a frequent illusion of nothing happening, when in fact a lengthy filesync is underway.

ornate vigilBOT
ornate vigilBOT
#

What happened? What did you expect to happen?

Dagger seems to try to interpret parts of the env variable: USER=an$example-user as a separate variable. I get the following error:
failed to get configured module: failed to resolve dep to source: failed to load git dep: select: load user defaults: Evaluate env file: USER: example: unbound variable
How do I escape the '$' in my env var? the documentation doesn't mention this behaviour. I pass this value as a regular argument to the dagg...

ornate vigilBOT
ornate vigilBOT
#

Currently a Go SDK module gets its own personal Dagger Go SDK client generated to ./internal/dagger which the module code then imports.

It also has a locally defined dag variable that is the instantiated Dagger client.

This has a few downsides:

  • Can't use a package for module and non-module code, since it's awkward for a module to depend on the external SDK
  • goimports sees undeclared dag and auto-imports dagger.io/dagger/dag which breaks everything - very annoying
  • Not always ...
ornate vigilBOT
ornate vigilBOT
#

What is the issue?

I'm observing that pulling large container images through Dagger takes approximately twice as long as pulling the same images directly with docker pull or podman pull.

Both tests were performed on the same machine with the same network conditions, pulling from the same registry.

Environment:

  • Dagger version: v0.19.8
  • OS: EndeavourOS, Linux 6.12.61-1-lts
  • Container runtime: Podman 5.7.0

Notes:

I'm not certain this is a bug - it may be expected beh...

#

@xfactor2000 thanks for the report, I'd consider that a performance bug as there's not any good reason there should be a difference pulling w/ dagger vs. other container engines (dagger mostly uses containerd libs for image pulling, which is I think what docker uses these days too).

I'm guessing you can't share the actual image you use to repro this (if you can though, that would be very helpful), but would it be possible to share a little more metadata? I'm specifically curious:

  1. how ma...
ornate vigilBOT
#

What is the issue?

The python SDK does not expose the cache parameter in its type stubs. I tried to submit an MR but CI lit up like a Christmas tree in #11571 so I'll make an issue instead! 😅

Even though the underlying python sdk func has a cache parameter, it's not exposed in the type hint overloads:

    @overload
    def function(
        self,
        func: Func[P, R],
        *,
        name: APIName | None = None,
        doc: str | None = None,
        deprecated: str ...
ornate vigilBOT
#

Description

[!NOTE]
AI wrote this issue. I have proofread/verified correctness to the best of my ability.

Calling .stdout() on Container objects in the Dagger TypeScript SDK consistently fails with:

Encountered an unknown error while requesting data via graphql
Caused by: Can only call URLSearchParams.toJSON on instances of URLSearchParams

This appears to be a GraphQL serialization bug where URLSearchParams instances are incorrectly serialized during SDK-to-engine communi...

ornate vigilBOT
#

Problem

[!NOTE]
AI wrote this issue. I have verified correctness to the best of my ability.

cache manager can't calculate disk usage for snapshots with deeply nested directories. hits ENAMETOOLONG when walking filesystem.

level=ERROR msg="failed to calculate size" error="lstat .../node_modules/.old-57CC/.../node_modules/.old-5AB6/.../astro-opengraph-images/...: file name too long"

seen with npm packages like astro-opengraph-images that create circular/deeply nested node_mod...

ornate vigilBOT
#

note this also causes a panic:

  time="2026-01-04T21:26:35Z" level=debug msg="snapshotter error" error="lstat
  /var/lib/dagger/worker/snapshots/snapshots/62979/fs/workspace/examples/preset/node_modules/astro-opengraph-images/examples/preset/node_modules/astro-opengraph-images/examples/preset/node_modules/astro-opengraph-images/examples/preset/node_modules/astro-opengraph-images/examples/preset/node_modules/astro-opengraph-images/examples/preset/node_modules/astro-opengraph-images/exampl...
#

@shepherdjerred Thanks for the report on the bug. There's a few significant problems with the approach in the linked PR, but more fundamentally the code that should handle this is from containerd, not our codebase.

I'm extremely curious how you are ending up in this situation in the first place though. The explanation at the bottom that there's a circular symlink doesn't add up to me for a few reasons:

  1. The implementation in containerd just uses go's stdlib filepath.Walk, which is docume...
#

What is the issue?

I've just started having problems creating Dagger modules using dagger init. See the console log below for example, but this is happening whether the directory is empty, is a n empty Git project root, is non-empty with non-git files, or a non-empty git root directory.

This is on Docker for Mac on sillicon hardware.

Dagger version

dagger v0.19.2 (image://registry.dagger.io/engine:v0.19.2) darwin/arm64/v8

Steps to reproduce

 11:28:00 ~
$ cd src/play...
ornate vigilBOT
ornate vigilBOT
#

What are you trying to do?

With env vars, I can attach them both as single vars or a set of vars from a file. In Kubernetes, I specify both env vars and secrets as env, using both line items and from file. Dagger is missing the SecretFile from the { Env, Secret } x { Var, File } cross-product.

Why is this important to you?

No response

How are you currently working around this?

No response

ornate vigilBOT
#

What is the issue?

I am using dagger connected to Amazon Bedrock through the bedrock-access-gateway (https://github.com/aws-samples/bedrock-access-gateway) when I submit a promo in the the run prompt mode in the dagger interactive shell I am getting the following error:

┃ 0.0s ERROR
! received error while streaming: {"message":"500: Parameter validation failed:\nInvalid length for parameter toolConfig.tools[12].toolSpec.description, value: 0, valid min length: 1"}

The raw requ...

#

I'm curious how an actual use of this SecretFile might look like.

The main purpose of EnvFile is to model the .env file used by user defaults (https://github.com/dagger/dagger/pull/11034) which is parsed and then injected appropriately into your module's fields, arguments, etc. Outside of that main use case, the EnvFile type doesn't have too much use since it can't be used with other types like Container for example.

Going back to SecretFile, it's not clear to me how and what th...

#

It's exactly the same idea, but secrets so they are obfuscated

Basically I'm after the way Kubernetes does it for both env and secrets, expose the whole file as env vars in one line, so the analog would be a single step to expose a set of env vars or secrets via a file

One note, External Secrets Operator (ESO) uses JSON format, so there are translations that would be nice if they were auto handled, this project is gaining usage in the k8s ecosystem where more of our dagger workloads are run...

#

Problem

When running 'dagger check' in a module, there is no distinction between:

a) checks meant to be run in the context of another module (by installing the current module as a toolchain)
b) checks meant to be run in the context of the current module

As a result, running 'dagger check' in a toolchain module, is likely to fail in confusing and unpredictable ways.

This complicates out-of-the-box CI for every Dagger module - because that requires a simple way to run every check on ...

ornate vigilBOT
#

I am using the bedrock-access-gateway (https://github.com/aws-samples/bedrock-access-gateway)

I haven't tried LiteLLM yet but that was on my list to try when I get back to testing things. I also could add a fix to the bedrock access gateway to watch for the blank description and make it not blank before passing it through to Amazon Bedrock.

My concern was if the module doesn't have a description in the tool spec it would make it hard for the LLM to know when it should look to use that modul...

ornate vigilBOT
#

Does that mean it will not be possible to define a check on a root module, only use toolchains?

Correct. (well technically, still possible, just will be silently ignored by default)

So if a specific check is needed, the solution would be for instance to create a sub module and reference it as a toolchain?

Yes exactly. This is the pattern we are already following on dagger/dagger, and I quite like it.

And maybe by extension to only toolchains in the main module, no custom code dire...

#

Hmm this feels like a big change - toolchains are great and all, but if I have to use (or worse, write) one to get started with a small side-project like Dang, that'll feel really really weird.

What about just throwing a flag in dagger.json for toolchain modules, so we can detect that they are only valid when used as a toolchain?

It's a little weird that all the users of a toolchain module know it's a toolchain, but the module itself doesn't. :grin:

#

the problem is that "toolchain" is relative. You can install a module as a toolchain, but you can also use it as your context (ie to test your own module). So setting a toolchain field doesn't really solve the problem. Either we disable all inline checks for toolchain modules (but then you can't develop your toolchain with the full dagger experience) or you don't disable anything (but then the original problem is not solved)

With the solution I propose you can install toolchains in your tool...

#

An alternative path is to design a better "context API", and change toolchains to use that. One requirement of that new context API, would be that toolchains would receive their context as an explicit value.

For example:

func New(env *dagger.Env) Go {
  return &Go{
    Source: env.Workspace().Directory("/"),    
  }
}

// ....

Then dagger toolchain install ... would hook up that env argument such that it gets a value.

In that case, our problem of "CI for toolchains" go...

#

(Wrote this before the previous two comments, submitting anyway - it's a bit ranty but think it's worth putting in writing)

tl;dr this feels like a solution downstream of a larger design problem, that is "I don't know wtf toolchain means anymore"

Lastly I think it feels weird to you to "have to develop an internal toolchain to do anything" but IMO it's because you're familiar with the pre-existing ".dagger" model. New users wilk find it more natural I think that everything is a toolchain....

#

Once we started implementing "single-user" toolchains like in dagger/dagger, I lost my intuition for what makes something a toolchain. Now you're telling me sometimes these Batman toolbelts have a Batman in them, and that Batman is the only entity expected to ever operate that toolbelt. So why is it billed as a toolbelt? What I have is a Batman and a toolbelt, or a context and its functions, and that's just a module.
Now it feels like two features hiding in one trenchcoat: mounting toolchai...

#

I can see the appeal of separating dev concerns out of module API concerns, since right now they're all mixed together. As a consumer of a module I don't really care about its test/build/ship functions, so moving those into toolchains makes sense. dagger/dagger could have a dagger module for programmatic use of Dagger as a product, and a dagger-dev toolchain which is what we have now, purely focused on developing Dagger, not consuming it through an API.

[...]
Wouldn't the `.dag...

ornate vigilBOT
#

No, what I want is the ability to fetch full information about the onepassword item including the available fields.

This is because sometimes my job doesn't know the available fields in advance. I want to discover them at runtime.

The exact use case is setting an environment variable from each field. I have different onepassword items (with different sets of fields) for prod, testing in CI and branch deployments. A .env file won't work here.

#

@danielgafni IIRC you're looking forward to fetch multiple fields when passing them via function arguments like this? https://docs.dagger.io/features/secrets/#hashicorp-vault-and-1password

Not sure if you saw user defaults (https://github.com/dagger/dagger/pull/11034) but you can populate all the values you need in a .env file and then inject those into your module's attributes or function arguments. Does this solve your issue?

ornate vigilBOT
#

NOTE: this is about a change to how we test the Dagger project. It is NOT about how Dagger runs tests.

For our e2e tests, we orchestrate service dependencies outside our test code. Recently we have discussed the benefits of orchestrating service dependencies in the test code. This made us realize that, for our own project, we should switch to this technique.

Benefits

In no particular order:

  • It will make @sipsma and @kpenfound happ...
#

If you're still looking for a solution @huhouhua, you can extract it via:

dag.container().from("alpine:latest").withExec(["sh", "-c", "export FOO=BAR && env > some-file"]).file("some-file").contents()

then parse the string as you would parse an .env file.

Note that you'll have to do this under the same exec since the environment variables won't persist between chained .withExec() calls.

ornate vigilBOT
#

What are you trying to do?

We are trying to build toolchains that offer a very standardized out-of-the-box experience with our templates. While doing this we noticed that it's not easy to design these without some arguments being repeated between the functions we expose.

For example, for our dotnet toolchain, we want to offer an override for the SDK image to be used. This is needed for pretty much all the features we expose and we end up with a large amount of repeated defaults in custo...

ornate vigilBOT
#

Another thought: this can perhaps be solved with self-calls. The user of the toolchain defines a customization on a "building block" presented by the toolchain, for example:

        {
          "function": ["dotnet_test_args"],
          "argument": "additional_dotnet_args",
          "default": "[\"--filter\", \"TestCategory!=Integration\"]"
        }

Then other functions in the toolchain that need the value will call this via a dagger function call instead of an "in-language" call...

#

What is the issue?

Follow-up of Discord discussion: https://discord.com/channels/707636530424053791/1465717553530671389

I have a context directory, which looks like (simplified)

    // +defaultPath="/"
    // +ignore=["**","!dagger.json"]
    source *dagger.Directory,

When calling a module without any arguments, the source is resolved as a "context" directory and the correct filters (exclude) are applied:

$ dagger call source-contents

dagger.json

However, if a...

ornate vigilBOT
#

What are you trying to do?

I'd like to be able to have more than one context for docker build from Dockerfile.

Why is this important to you?

It would ease quite a lot the adoption of dagger on projects with massive Dockerfile to migrate over to dagger. That way we could focus on orchestrating other parts of the CI instead of the build itself.

How are you currently working around this?

I am not.

ornate vigilBOT
#

Every Go module contains a bunch of boilerplate to work properly and integrate with the IDE.

A regular dagger go module is composed of the following generated files:

├── dagger.gen.go <--- module support static generation + dagger global client used in the module
├── internal
│   ├── dagger/dagger.gen.go <--- Client bindings to query the dagger engine, include core and dependencies bindings.
│   ├── querybuilder/
│   └── telemetry/

Note: querybuilder and telemetry are staticall...

ornate vigilBOT
#

What are you trying to do?

I'd like if we could have support to specify a custom tsconfig.json for the TypeScript SDK, something along the lines of:

{
  "sdk": {
    "source": "typescript",
    "config": "tsconfig.dagger.json"
  },
  "source": ".dagger"
}

Why is this important to you?

I have a monorepo that is using composite projects, so I'd like if my language server and tools can run type checks and include my Dagger sources as well, without having to have a separate ...

#

Problem

As of 0.19.11, generated clients are smaller: they import dagger.io/dagger for core types, instead of duplicating it. This includes dagger.io/dagger/telemetry.

This broke a small number of modules (all internally used by us) that manually imported their generated dagger/telemetry package, to use our experimental otel features (attribute definitions etc). As a result these modules fail to load with v0.19.11.

Known affected modules:

Directly affected:

#

There's another issue which is that after fixing the imports, if you build a dev engine the expected imports actually go back to being required in the previous format. This affects a ./hack/dev dev engine, a dev engine service container, our ci:bootstrap job, etc.

@sipsma out of curiosity, if all codegen were moved out of runtime (in other words: if engine generated zero code while loading a module) would that last problem have been avoided?

#

What is the issue?

I have a larger repository which I've adopted to use Dagger. This repository contains a .env file with ~220 env variables, all unrelated to Dagger, which is copied from a .env.template for local dev. I've noticed significant slow downs to module loading when the .env file is present (~1.9s w/o .env, ~26s w/ .env).

This directly impacts all uses of Dagger within this repository.

There looks to be some prior discussion on configuring the env file loading in h...

#

What is the issue?

I'm not certain how to this occurred, but I wanted to record the error here. I was refactoring an existing module, moving/deleting code (a Release struct) from one module (mod A) to a new one (mod B). When I called dagger functions on mod A the CLI errors with:

$ dagger functions

✘ load module: . 2.2s ERROR
✘ initializing module 0.3s ERROR
! Post "http://dagger/query": command [docker exec -i dagger-engine-v0.19.11 buildctl dial-stdio] has
  exited with exit ...
#

Here's a script that will setup the conditions to replicate this bug:

#!/bin/sh
set -e

mkdir example && cd example || (echo "please delete example directory before running this script" && exit 1)

git init .

cat > dagger.json <<EOF
{
  "name": "theroot",
  "engineVersion": "v0.19.11",
  "sdk": {
    "source": "go"
  },
  "toolchains": [
    {
      "name": "somemodulename",
      "source": "somemodule"
    }
  ]
}
EOF

mkdir somemodule
cat > somemodule/dagger.json <<EOF
{
  "name": "so...
#

What is the issue?

The casing of the function and argument field seem to be the casing of the actual implementation.

For example in the go default example, the functionName is ContainerEcho. I don't think this is by design because it is surprising, considering other views on function names are standardized for the environment they are being used in. My first instinct was to use the names as shown by the CLI when using help commands or invoking things.

If it is by design and shoul...

#

Bug Description

After a Dagger session completes (or fails), the BuildKit solver's in-memory vertex cache (actives map) can retain stale session ID references. When a new session connects and resolves the same LLB vertex digests (same Dagger module, same code), the solver reuses the cached vertex state. The reused state's NextSession() iterator walks parent states and finds the dead session ID, causing a 5-second timeout per cache key lookup. Every subsequent job fails within ~10 seco...

ornate vigilBOT
#

What is the issue?

When I'm setting a json value in a variable for an envfile quotes are stripped.

ENV_JSON_ISSUE={foo: bar}
ENV_JSON_GOOD={"foo": "bar"}

Dagger version

dagger v0.19.11 (image://registry.dagger.io/engine:v0.19.11) linux/amd64

Steps to reproduce

import dagger
from dagger import dag, function, object_type

import json


@object_type
class DaggerBug:
    @function
    async def env_file_bug(self) -> str:

        return await (
            dag.
...
#

What is the issue?

Setting OTEL_EXPORTER_OTLP_METRICS_ENDPOINT on the Dagger engine process has no effect — metrics are never exported to external OTLP collectors.

Root cause

cmd/engine/telemetry.go:53-55 calls telemetry.Init() without Detect: true:

ctx = telemetry.Init(ctx, telemetry.Config{
    Resource: otelResource,
})

When Detect is false (zero value), Init() at sdk/go/telemetry/init.go:398 skips the block that calls ConfiguredMetricExporter() — t...

ornate vigilBOT
#

Description

When using _EXPERIMENTAL_DAGGER_CACHE_CONFIG with an S3 backend, the Dagger engine crashes with a Go stack overflow during the cache export phase on the second run of a pipeline. The first run succeeds and populates the S3 cache. Any subsequent run that imports this cache and then tries to re-export crashes the engine.

Environment

  • Dagger version: v0.19.11
  • Engine: Remote engine on EC2 (Amazon Linux 2023, c7i.xlarge24, 192GB RAM)
  • Cache config: `type=...
#

What is the issue?

dockerfile-build is unable to build a dockerfile that runs a heredoc script.

Dagger version

dagger v0.20.0 (image://registry.dagger.io/engine:v0.20.0) linux/amd64

Steps to reproduce

Consider the following Dockerfile:

# syntax=docker/dockerfile:1
FROM alpine
RUN < data

Then try to build it with dagger:

dagger -c 'directory | with-file . $(host |file "Dockerfile") | docker-build | sync'

it fails with:

✘ sync 1.2s ERROR
! p...
ornate vigilBOT
#

Context

Container.dockerHealthcheck (as an example, but this might probably be hit by other API methods) can resolve to null, with the docker equivalent of:

FROM alpine
HEALTHCHECK NONE

When exposed using the Dagger API, the Python codegen exposes docker_healthcheck() as a concrete HealthcheckConfig type and scalar accessors (shell(), args()) as non-null values.

This leads to an error, at runtime, in which the Python SDK raises **Required field got a null re...

ornate vigilBOT
#

What are you trying to do?

Building Dagger release archives should produce bit-for-bit identical assets on every run.

Why is this important to you?

For v0.20.1 our publish job flaked out, and we had to delete the GitHub release in order to re-run it (not idempotent - separate issue). When publish finally succeeded, we had a mix of opinions on what the checksums should be for our archives, between Nix, our checksums.txt on dl.dagger.io, our CDN, our S3 bucket, etc. - a huge ...

#

What is the issue?

https://github.com/dagger/dagger/blob/f8c23f77772249bb5a480e7044b5345df89f5f62/helm/dagger/templates/engine-daemonset.yaml#L127-L146

Hey all, I tried to configure a custom liveness probe on my dagger engine but ended up having next error,


rror while running post render on files: map[string]interface {}(nil): yaml: unmarshal errors: │
│ line 110: mapping key "exec" already defined at line 104

Reason is: it is not possible to have two readinessprobes for the ...

ornate vigilBOT
#

What is the issue?

A TypeScript module function returning Promise that runs multiple parallel checks via Promise.all — including one that uses .withServiceBinding() to bind an .asService() container — fails when the service's underlying withExec exits non-zero.

The Dagger TUI output (--progress=dots) clearly shows the error:

): Void 5m17s ERROR

✘ withExec sh -c '...' 1m12s ERROR
! exit code: 1

✘ withExec sh -c '...' 2m23s ERROR
! start  (aliased as ): exit code: 1
```...
ornate vigilBOT
#

What is the issue?

dagger init fails if there's a directory called .env in any of the parent directories.

Dagger version

dagger v0.20.1 (image://registry.dagger.io/engine:v0.20.1) linux/amd64

Steps to reproduce

sh -c 'cd $(mkdir -d) && pwd && mkdir .env && mkdir example && cd example && dagger init'

Log output

✔ connect 0.1s

✘ moduleSource(refString: ".", disableFindUp: true, allowNotExists: true, requireKind: LOCAL_SOURCE): ModuleSource! 0.0s ERROR
┇...
ornate vigilBOT
#

Hi, I've been looking into this and traced the root cause.

Proposed approach: The error originates in moduleSource when resolving .env files in parent directories. The fix is to add an IsDir check before attempting to read .env as a file — if the path is a directory, skip it. Look in the engine's module source resolution logic (likely in core/ or engine/ under dagger), find where Host.file(path: '../.env') is called, and add a guard: if the path resolves to a directory, treat it as n...

#

What is the issue?

Running WithExec with these options:

dagger.ContainerWithExecOpts{
   Expect:         expectedResult,
   RedirectStdout: reportPath,
   Expand:         true,
},

Where reportPath = $HOME/artifacts

Results in an error open redirect stdout file: open /tmp/rootfs1507444385/$HOME/artifacts

It looks like Expand is not applying to RedirectStdout option.

Dagger version

0.20.1

Steps to reproduce

Run WithExec with the options and configuration in the desc...

ornate vigilBOT
#

We've received numerous requests in just the past couple of weeks for more ability to control the UI.

At a base level, we know we don't want developers to have to work directly with the OpenTelemetry SDK like they have to now. But it's not just that: some users also want more control over where things show up in the UI, and want the ability to show something instead of the lower-level details, so we need to figure out the rules for that, too.

This issue is to corral all the feedback...

vivid lintelBOT
ornate vigilBOT
#

Apologies if this doesn't have enough context or supporting info. I want to share the sentiments I posted on Discord so they don't get lost

The standard --progress=plain is still too verbose. It gets very crowded when there are multiple module dependencies. I'd almost want something that shows stdout of my immediate withExecs with the ability to set custom "spans" as labels. As a dagger power user, even I can barely understand what's going on and I can see others being very confused by...

#

I'll throw in my question in Discord from a while back as well
#1292749813397327954 message

The sentiment definitely still remains. For me, even in CI (--progress plain / not interactive) I would generally like to have the option to only show user/domain output that I as tool/pipeline author have chosen, without the verbose dagger engine output. For a successful call, that output is pretty much never useful. And although useful if...

ornate vigilBOT
#

[!NOTE]
This issue allows to track progress, ideas, feedback about a Dagger Java SDK.

[!WARNING]
🚧 This is in progress, the lists below are not exhaustive and can change over time

Needs for a first release

  • [x] Entrypoint generation: see #9422
  • [x] dagger init --sdk=java: #9422
  • [x] dagger develop: #9422
  • [x] better support of optional / default: support the full matrix of possibilities: see #9422
  • [x] support fields: #9520
  • [x] support defaultPath and `igno...
vivid lintelBOT
ornate vigilBOT
#

Problem

When dagger call calls a function that returns a Changeset, the CLI prompts the user to apply the changes to the local filesystem.

Unfortunately, the changes are applied relative to the CLI's working directory, which is brittle and often surprising.
This means that the same command will fail or succeed (or worse, silently dump data in the wrong place) depending on the workdir.
This is surprising because the rest of dagger call doesn't behave differently based on workdir, ...

#

Hard agree with this.

We can sort of track the origin of what a Changeset applies to by tracking the ancestor of Before, and work out way back to a Host.directory (similar to the approach in #11158).

Wondering what this API would look like 🤔 Something like ChangeSet.exportToOrigin? Whatever we end up with, would be nice to have a Directory.exportToOrigin equivalent as well.

One thing to note, we'd need to make sure that a function like this would still have a way to prompt, showi...

#

The tricky thing here will be detecting the origin of Host.directory(/foo).directory(bar) as /foo/bar. I don't think that's even that much of an edge case, since "scoping down" a Directory to pass it in to a lower subsystem is pretty normal. 🤔

That makes me think the *Directory object itself should retain this metadata, rather than trying to figure it out through static ID or LLB analysis.

ornate vigilBOT
#

This proposal aims to address LLM access control from https://github.com/dagger/dagger/issues/9801. However, I think it's worth considering future use cases as well - there's other cases (especially in an enterprise scenario!) where we'll want to control security per-modules:

  • allowing access to InsecureRootCapabilities, and other similar settings
  • we could even consider opening up dag.Host access safely for some some modules with this control? maybe?

With that in mind, in this i...

#

if I don't trust the module to run completely wild with my remote LLM, but still want to give it limited access, then I think it would be good to have to set a module-wide limit, not just directly at the dag.llm() level.

this is probably true, but there are many dimensions and ways that one might want to limit a module's access to the LLM, hard vs soft limits on tokens, api calls, context windows sizes, etc... further afield you can even imagine a world where scheduling concepts like reso...

ornate vigilBOT
#

Is there no value in having token caps as part of the permissions granted? I get that we have maxApiCalls/maxTokens, but that's still controlled by the caller of dag.llm().

If I want to limit the maximum that dag.llm() is allowed for a module, e.g. if I don't trust the module to run completely wild with my remote LLM, but still want to give it limited access, then I think it would be good to have to set a module-wide limit, not just directly at the dag.llm() level.

Agreed we can t...

#

Problem

The Dagger API has 6 different reference docs:

  • GraphQL
  • Go
  • Python
  • Typescript
  • PHP
  • Java

This is very frustrating because it's impossible to link to a single page to reference a given API type or function. Instead I have to either 1) ask or guess the most relevant language, then search in the corresponding reference doc, or 2) link to the language-agnostic GraphQL reference, which is usually too low-level for most people.

Solution

Develop a single reference API refe...

ornate vigilBOT
#

In #8839 and #8587, we added basic dagger update functionality (as described in #6605). Today, running dagger update only refreshes the dependency pins to the original ref.

For example, if mymodule@main was installed, then updating will refresh the pin to the current state of the main branch. However, this doesn't work particularly well with tags - updating mymodule@v1.2.3 just refreshes to the state of the v1.2.3 tag, but doesn't actually update the tag itself.

In this [disco...

#

I think this is getting dangerously close to real package management. 😄

TBH I haven't seen this style of dependency update yet (though I'm not well-versed in all package managers out there)

I would propose an alternative which might be more complicated to implement (or not if there is already a library out there): version constraints.

Examples:

  • >=1.0 - anything above (including) 1.0.0
  • >=1.0 <2.0.0 - anything between 1.0.0 and 2.0.0
  • ~1.2 - equivalent to >=1.2 <2.0.0

The ups...

#

I think this is getting dangerously close to real package management. 😄

Yeah maybe it's time to just bust out the big guns, admit we're gonna do it.

I would propose an alternative which might be more complicated to implement (or not if there is already a library out there): version constraints.

I'm up for that - in that case we don't need ModuleBumpMode as I described above (which yea, is weird), we'd just need a boolean bump: Boolean.

Examples:

Where does the constraint go tho...

#

I'm up for that - in that case we don't need ModuleBumpMode as I described above (which yea, is weird), we'd just need a boolean bump: Boolean.

I don't think that's necessary. You would just run dagger update, wouldn't you? Or am I missing something?

Where does the constraint go though?

Here is how I would expect it to work as a user:

dagger install installs the latest version, but saves a constraint that allows updating within the same major version. Since we use semver, withi...

ornate vigilBOT
ornate vigilBOT
#

I did some more testing, and adding a sleep before re-throwing seems to do the trick.

await connection(async () => {
  const dir = dag.directory().withNewFile("Dockerfile", readFileSync("./scripts/Dockerfile").toString())
  const container = dag.container().build(dir);

  const result = await container.sync().catch((e: Error) => {
    return e;
  });


  if(result instanceof Error) {
      await new Promise(resolve => setTimeout(resolve, 3000));
      throw result;
  }
}, { LogOutput: p...
ornate vigilBOT
ornate vigilBOT
vivid lintelBOT
#

Discussed in https://github.com/dagger/dagger/discussions/12818

Originally posted by rrati March 20, 2026

What is the issue?

Running WithExec with these options:

dagger.ContainerWithExecOpts{
   Expect:         expectedResult,
   RedirectStdout: reportPath,
   Expand:         true,
},

Where reportPath = $HOME/artifacts

Results in an error open redirect stdout file: open /tmp/rootfs1507444385/$HOME/artifacts

It looks like Expand is not applying to RedirectStdout op...

#

Discussed in https://github.com/dagger/dagger/discussions/12817

Originally posted by alexcb March 17, 2026

What is the issue?

dagger init fails if there's a directory called .env in any of the parent directories.

Dagger version

dagger v0.20.1 (image://registry.dagger.io/engine:v0.20.1) linux/amd64

Steps to reproduce

sh -c 'cd $(mkdir -d) && pwd && mkdir .env && mkdir example && cd example && dagger init'

Log output

✔ connect 0.1s

✘ moduleS...
ornate vigilBOT
vivid lintelBOT
#

What is the issue?

A TypeScript module function returning Promise that runs multiple parallel checks via Promise.all — including one that uses .withServiceBinding() to bind an .asService() container — fails when the service's underlying withExec exits non-zero.

The Dagger TUI output (--progress=dots) clearly shows the error:

): Void 5m17s ERROR

✘ withExec sh -c '...' 1m12s ERROR
! exit code: 1

✘ withExec sh -c '...' 2m23s ERROR
! start  (aliased as ): exit code: 1
```...
#

Discussed in https://github.com/dagger/dagger/discussions/12816

Originally posted by moltar March 12, 2026

What is the issue?

A TypeScript module function returning Promise that runs multiple parallel checks via Promise.all — including one that uses .withServiceBinding() to bind an .asService() container — fails when the service's underlying withExec exits non-zero.

The Dagger TUI output (--progress=dots) clearly shows the error:

): Void 5m17s ERROR

✘ withE...
ornate vigilBOT
#

What is the issue?

A TypeScript module function returning Promise that runs multiple parallel checks via Promise.all — including one that uses .withServiceBinding() to bind an .asService() container — fails when the service's underlying withExec exits non-zero.

The Dagger TUI output (--progress=dots) clearly shows the error:

): Void 5m17s ERROR

✘ withExec sh -c '...' 1m12s ERROR
! exit code: 1

✘ withExec sh -c '...' 2m23s ERROR
! start  (aliased as ): exit code: 1
```...
ornate vigilBOT
vivid lintelBOT
#

What are you trying to do?

[!NOTE]
Initially discussed in https://github.com/dagger/dagger/discussions/11683

The same way we have check and generate functions, add up functions.
A up function must return a dagger.Service instance that will be started and exposed.

With a single dagger up command, all the up functions will have their services started. Of course those services can come from multiple toolchain modules. That way we can compose and combine multiple services...

vivid lintelBOT
#

Tried handing a native dang module to an LLM and found that quite a few things were missing or not actually supported:

  • Workspace arguments weren't able to do filesync - the Dang SDK uses a synthetic client ID which went nowhere, now it proxies through to the main client
  • @check, @generate, enums, interfaces, and custom scalars were all not carried over from github.com/vito/dang/dagger-sdk
  • Telemetry was wonky - the LLM would routinely miss logs that were emitted, because of...
vivid lintelBOT
#

Summary

  • fix the custom registry mirror docs example so it executes /hello before reading stdout
  • align the docs example with the built-in dagger query --help example
  • note that debug output can still show the canonical docker.io/... ref and that mirror verification should use registry access logs

Verification

  • reproduced the broken query locally and got container.from.stdout no command has been set
  • verified the corrected query succeeds with a fresh engine started from ...
vivid lintelBOT
#

Here is a set of minor fixes/improvements made while testing the rust dagger sdk:

  • Fix Config.timeout and Config.execute_timeout not being used: a hardcoded 1000s execute timeout was applied instead
  • Add a Config::builder() API
  • Fix clippy lints
  • Fix GraphQL error parsing: cmd, exit code, stdout, stderr are now accessible in GraphQlExtension::ExecError
vivid lintelBOT
#

Summary

This report was previously moved to discussion #12769, but it is actionable and reproducible, so tracking it here as an issue.

Problem

The custom registry mirror docs currently recommend:

dagger query --progress=plain <<< '{ container { from(address:"hello-world") { stdout } } }'

That fails with:

container.from.stdout no command has been set

because Container.stdout requires a previously executed command.

Expected

The docs example should exe...

ornate vigilBOT
vivid lintelBOT
#

Problem

When using dagger.connection() without log_output (the default), the terminal cursor disappears and the Rich spinner animation may hang after the connection closes. This affects anyone using the Python SDK from a REPL, script, or notebook.

Root Cause

In sdk/python/src/dagger/provisioning/_engine.py, the Progress status spinner is started during provisioning but progress.stop() is only called when cfg.log_output is set (line 127-128). In the default path (no `log_o...

#

Summary

  • Always call progress.stop() on shutdown, ensuring the terminal cursor is restored regardless of log_output configuration
  • Previously, stop() was only called when log_output was set, leaving the cursor hidden in the default path

Root Cause

Progress.start() emits ANSI \x1b[?25l (hide cursor) via Rich's Status spinner. Progress.stop() emits \x1b[?25h (show cursor). But stop() was only called when cfg.log_output was configured — in the default path, the s...

ornate vigilBOT
#

Hey @JimDabell — apologies for the slow response on this, and for incorrectly moving it to a discussion. This is a legitimate bug and should have stayed as an issue.

We've tracked it as a new issue at #12834 and a fix is up at #12835. The root cause was that Progress.stop() (which restores the terminal cursor) was never called in the default code path — only when log_output was explicitly configured.

Thanks for the detailed report.

#

Hey @JimDabell — apologies for the slow response on this, and for incorrectly moving it to a discussion. This is a legitimate bug and should have stayed as an issue.

We've tracked it as a new issue at #12834 and a fix is up at #12835. The root cause was that Progress.stop() (which restores the terminal cursor) was never called in the default code path — only when log_output was explicitly configured.

Thanks for the detailed report.

vivid lintelBOT
#

Bug

dagger.Config(log_output=...) is documented as accepting TextIO, but subprocess.Popen requires the stream to have a real file descriptor (fileno()). Passing an in-memory stream like io.StringIO crashes with a cryptic error:

dagger.SessionError: Failed to start Dagger engine session: fileno

Reproduction

import asyncio, io, dagger
from dagger import dag

async def test():
    buffer = io.StringIO()
    cfg = dagger.Config(log_output=buffer)
    async wi...
#

Summary

  • Config(log_output=...) accepts TextIO but subprocess.Popen(stderr=...) requires a real file descriptor — passing StringIO crashes with SessionError: Failed to start Dagger engine session: fileno
  • When log_output lacks fileno(), use os.pipe() + a forwarding thread so any TextIO works as documented
  • Streams backed by real file descriptors (e.g. sys.stderr, open(...)) are still passed directly to Popen (no behavior change)

Fixes #12836
Originally reported i...

ornate vigilBOT
vivid lintelBOT
#

Bug

Directory.diff() fails with:

failed to compute cache key: failed to calculate checksum of ref ... "/usr/lib": not found

Reproduction

import dagger

async def main():
    async with dagger.connection():
        base = dagger.container().from_("debian:bookworm-slim")
        modified = base.with_exec(["apt-get", "update"]).with_exec(["apt-get", "install", "-y", "zlib1g"])

        base_dir = base.directory("/usr/lib")
        modified_dir = modified.directory("...
ornate vigilBOT
vivid lintelBOT
#

Bug

Panic (index out of range) when resizing or exiting an interactive terminal session. Caused by a bug in the midterm library's Screen.resizeX() where v.Width was updated after the shrink loop, causing ensureHeight() to create rows with the old width while content was already truncated.

Status

Fixed in v0.19.1 via PR #11164 (midterm commit 08bad7a1d2ea), which includes a regression test. All reporters were on v0.18.x; no reports since v0.19.1.

Originally reported in https:...

ornate vigilBOT
vivid lintelBOT
#

Bug

In dagger shell, passing a plain string where a custom object type is expected produces cryptic internal errors like:

error: parse selections: parse field "test": init arg "config" value as core.DynamicID
(TestmodMyConfigID!) using core.DynamicID: decode "TestmodMyConfig" ID: failed to unmarshal
proto: proto: cannot parse invalid wire-format data

dagger call correctly skips unsupported-type functions with a warning, but dagger shell exposes them and lets the raw string...

ornate vigilBOT
#

Sorry about the slow response here, and for incorrectly moving this to a discussion.

This is a real bug — dagger shell exposes functions with custom object arguments but gives cryptic protobuf/base64 errors when you pass a plain string. dagger call handles this better by skipping unsupported-type functions with a warning.

I've opened an issue and a PR with a fix that validates the argument type early and gives a clear error message telling you to use a constructor via command substi...

#

Sorry about the slow response here, and for incorrectly moving this to a discussion.

This is a real bug — dagger shell exposes functions with custom object arguments but gives cryptic protobuf/base64 errors when you pass a plain string. dagger call handles this better by skipping unsupported-type functions with a warning.

I've opened an issue and a PR with a fix that validates the argument type early and gives a clear error message telling you to use a constructor via command substi...

vivid lintelBOT
#

Summary

  • dagger shell gives cryptic protobuf/base64 errors when passing a plain string where a custom object type is expected
  • Validates in parseFlagValue that plain strings aren't passed for object/input types without custom flag support
  • Addresses the existing TODO comment at line 721: "This will likely fail if value doesn't come from command expansion"

Before: failed to unmarshal proto: proto: cannot parse invalid wire-format data

After: `argument "config" expects a ...

vivid lintelBOT
ornate vigilBOT
vivid lintelBOT
#

Summary

  • WithExec with Expand: true now expands environment variables in RedirectStdout, RedirectStderr, and RedirectStdin paths, not just command args.
  • Adds integration tests for redirect path expansion.

Fixes https://github.com/dagger/dagger/discussions/12818

Test plan

  • [ ] New integration tests: TestExecRedirectStdout and TestExecRedirectStdin with env var expansion
  • [ ] Existing expand tests continue to pass
vivid lintelBOT
ornate vigilBOT
ornate vigilBOT
vivid lintelBOT
#

Summary

  • When SSH_AUTH_SOCK is set but points to a stale/broken socket, module codegen no longer crashes with a cryptic EOF error.
  • Instead, SSH agent forwarding is skipped. If something downstream needs SSH (e.g. private git deps), it fails with a clear auth error.

Fixes https://github.com/dagger/dagger/discussions/12660

Repro

rm -rf /tmp/test-ssh-sock && \
  SSH_AUTH_SOCK=/tmp/doesnotexist dagger init --sdk=go /tmp/test-ssh-sock && \
  SSH_AUTH_SOCK=/tmp/doesnotexist d...
ornate vigilBOT
vivid lintelBOT
#

Summary

  • When CA certs are mounted from a K8s Secret (without subPath), files are symlinked through a ..data/ subdirectory. These symlinks break inside containers where ..data/ doesn't exist.
  • ReadHostCustomCADir now resolves symlinks to file contents instead of preserving them, so certs work regardless of mount structure.

Fixes https://github.com/dagger/dagger/discussions/12739

Repro

Deploy Dagger via helm with CA certs mounted from a K8s Secret:

helm upgrade --i...
ornate vigilBOT
ornate vigilBOT
vivid lintelBOT
#

When a Python SDK module constructor has an optional Secret argument with a default of None, and a .env file provides a value via env:// syntax, the engine finds and logs the .env value but it never reaches the Python constructor -- the argument stays None.

Repro

mkdir /tmp/test-env-default && cd /tmp/test-env-default
dagger init --sdk python --name testenvdefault

# Write module code
cat > src/testenvdefault/main.py  .env

# Run -- expect "secret is: hello-from-env", g...
vivid lintelBOT
#

Summary

  • Fix .env user defaults being silently ignored when a constructor arg has a schema default value (e.g. Python's dagger.Secret | None = None)
  • Root cause: CacheConfigForCall checked the args map (which includes schema defaults from ExtractIDArgs) instead of the call ID args (which only contain user-explicit inputs)
  • Add UserDefault.CallInput(ctx) method that handles object types, as defense-in-depth

Root cause

In dagql/objects.go, ExtractIDArgs populates the `...

ornate vigilBOT
ornate vigilBOT
vivid lintelBOT
ornate vigilBOT
vivid lintelBOT
#

When a module function has no description/docstring, Dagger passes an empty string as the tool description to LLM providers. Some providers (e.g. AWS Bedrock) require non-empty tool descriptions and reject the request.

Error from AWS Bedrock:

Parameter validation failed:
Invalid length for parameter toolConfig.tools[12].toolSpec.description, value: 0, valid min length: 1

Fix: fall back to "TypeName fieldName" (e.g. "MyModule build") when description is empty.

Fix in PR #PENDING.

O...

#

Summary

  • When a module function has no description, fall back to "TypeName fieldName" (e.g. "MyModule build") instead of passing an empty string to LLM providers
  • Some providers like AWS Bedrock require non-empty tool descriptions and reject requests with description: ""

Test plan

  • [ ] Verify dagger shell works with modules that have undocumented functions when using AWS Bedrock

Fixes #12856

ornate vigilBOT
vivid lintelBOT
ornate vigilBOT
vivid lintelBOT
#

Summary

  • The Helm chart hardcoded exec probe commands in the DaemonSet and StatefulSet templates, then appended readinessProbeSettings/livenessProbeSettings from values. This produced duplicate YAML keys when users customized probes, causing unmarshal errors.
  • Move the default exec command into values.yaml defaults and render the full probe from values in both templates.
  • Add TestCustomProbes check to toolchains/helm-dev that verifies custom probe overrides work.

Test...

#

Custom liveness/readiness probe settings via readinessProbeSettings / livenessProbeSettings in values.yaml produce duplicate exec YAML keys because the templates hardcode the exec command and then append the settings.

For example, setting a custom exec command:

engine:
  readinessProbeSettings:
    exec:
      command: ["sh", "-c", "echo ready"]

Results in:

readinessProbe:
  exec:           # hardcoded in template
    command: [...]
  exec:           # from values
...
ornate vigilBOT
vivid lintelBOT
ornate vigilBOT
vivid lintelBOT
vivid lintelBOT
#

Summary

  • Exclude new gosec taint-analysis rules (G117, G118, G122, G602, G702, G703, G704) that fire on intentional patterns (shutdown goroutines, config/env paths, API serialization, content-addressed filesystem ops, bounds-checked loops)
  • Exclude staticcheck QF1012 (fmt.Fprintf vs WriteString(fmt.Sprintf)) consistent with existing QF exclusions
  • Fix gocritic deprecatedComment in core/modules/config.go (blank line before Deprecated: per godoc convention)

Each rule was revie...

ornate vigilBOT
vivid lintelBOT
vivid lintelBOT
ornate vigilBOT
vivid lintelBOT
#

Summary

  • Add progress.stop() callback to AsyncExitStack in _engine.py so the Rich spinner properly restores the terminal cursor when the connection is closed

Root Cause

When using dagger.connection() without log_output, the Rich Status spinner hides the cursor via ANSI escape (\x1b[?25l). On exit, progress.stop() is never called, so the cursor remains permanently hidden.

Fix

Register progress.stop() as an AsyncExitStack callback (LIFO order ensures it runs afte...

#

Summary

  • Handle TextIO streams without fileno() (e.g. io.StringIO) in Config.log_output
  • Use a background daemon thread to forward subprocess stderr to the in-memory stream

Root Cause

subprocess.Popen requires stderr to have a real file descriptor via fileno(). In-memory streams like StringIO raise UnsupportedOperation: fileno causing SessionError.

Fix

  • Add _has_fileno() helper that safely checks if a stream has a file descriptor
  • When log_output lacks `fi...
#

Summary

  • Add regular-file checks in innerEnvFile() and outerEnvFile() to skip directories named .env

Root Cause

dagger init crashes when .env exists as a directory because:

  • innerEnvFile() uses directory.exists(".env") which returns true for directories
  • outerEnvFile() uses host.findUp(".env") which matches directories via Stat
    Both then call host.file() which fails on directories.

Fix

  • innerEnvFile(): Add expectedType: REGULAR_TYPE to the exists che...
ornate vigilBOT
#

When AI agents are triggered by CI/CD failures, they often guess at fixes without investigating the root cause.

claude-debug enforces investigation-before-fix via PreToolUse hooks:

  1. Reproduce the CI failure locally (edits blocked)
  2. Isolate which stage/step fails
  3. Root cause analysis (confirm before fixing)
  4. Minimal fix to confirmed cause
  5. Verify the pipeline passes

The reproduce phase is critical for CI debugging — the agent must reprod...

ornate vigilBOT
vivid lintelBOT
#

What is the issue?

When attempting to .with_exec a cargo build running in dagger, the dagger fails to start the build and hangs without starting the build

Dagger version

dagger v0.20.3 (image://registry.dagger.io/engine:v0.20.3) linux/amd64

Steps to reproduce

git clone https://github.com/robertu94/repostats
git co dev
dagger call web
# during the cargo build use `q` to exit
dagger call web
# at this point it hangs.

Log output

dagger call web
✔ connect 0.4s...

vivid lintelBOT
#

Summary

Adds GitHub Copilot as a first-class LLM provider for Dagger, using the official github.com/github/copilot-sdk/go SDK.

Closes discussion: https://github.com/dagger/dagger/discussions/12689

Motivation

GitHub Copilot subscribers have access to powerful models (GPT-4o, Claude Sonnet, etc.) via their existing Copilot license. This adds Copilot as a zero-extra-cost LLM option for Dagger users who already have Copilot access - no separate...

ornate vigilBOT
#

I'm building an apk file with a file name containing the build date, e.g. 2026-03-28-debug.apk.
My dagger function:

  @func()
  async getDebugApk(@argument({ defaultPath: "/"}) source: Directory): Promise {
    const dir = this.assembleDebug(source)
      .directory("app/build/outputs/apk/debug")
    const file = (await dir.glob("*.apk"))[0]
    return dir.file(file)
  }

If I export the file to the host with the command as follows

dagger call get-debug-apk exp...
ornate vigilBOT
ornate vigilBOT
#

In an effort to use new learnings with Agents and leveraging a new harness my team is internally using on top of github copilot (via the GHCP SDK) - I've been able to get all of the missing features (like tools) added to the original effort as well as migrate over to the current GitHub Copilot SDK (really an SDK on top of the CLI but that's just "details"). Currently working through fixing some of the errors in a draft PR - some seem to be existing issues from dagger main - some was just me/...

vivid lintelBOT
vivid lintelBOT
#

Updates the requirements on uv-build to permit the latest version.
Updates uv-build to 0.11.2

Release notes
Sourced from uv-build's releases.

0.11.2
Release Notes
Released on 2026-03-26.
Enhancements

Add a dedicated Windows PE editing error (#18710)
Make uv self update fetch the manifest from the mirror first (#18679)
Use uv reqwest client for self update (#17982)
Show uv self update success and failure messages with --quiet (#18645)

Preview features

...

#

Bumps the sdk-java group in /sdk/java with 1 update: io.vertx:vertx-web-client.

Updates io.vertx:vertx-web-client from 4.5.25 to 4.5.26

Commits

143b384 Releasing 4.5.26
5f1ad8d Subrouter failure handler is ignored (#2779) (#2858)
2287b82 [Issue-1506] Provide a method to get sub router if current route acts as a su...
21f5abf Set next snapshot version
See full diff in compare view

Most Recent Ignore Conditions Applied to This Pull Request

| De...

#

Bumps the sdk-python-docker group with 1 update in the /modules/ruff/build directory: astral-sh/ruff.

Updates astral-sh/ruff from 0.15.7 to 0.15.8

Release notes
Sourced from astral-sh/ruff's releases.

0.15.8
Release Notes
Released on 2026-03-26.
Preview features

[ruff] New rule unnecessary-if (RUF050) (#24114)
[ruff] New rule useless-finally (RUF072) (#24165)
[ruff] New rule f-string-percent-format (RUF073): warn when using % operator on an f-string ...

ornate vigilBOT
vivid lintelBOT
vivid lintelBOT
#

What is the issue?

Problem

When a Dagger module function internally creates a URI secret (e.g., dag.Secret("cmd://...") or dag.Secret("env://...")) and returns a result referencing it, a different session that gets a dagql cache hit on that function call cannot resolve the secret, causing secret : not found errors.

Reproduction

  1. Module function creates a URI secret internally (not passed as argument) and returns a container using it (e.g., WithSecretVariable)
  2. Sessio...
ornate vigilBOT
vivid lintelBOT
vivid lintelBOT
#

Zig mirror changed, and one of the consequence is some of the modules using Dang as the SDK might not work anymore.
In toolchain tests, we are using two different commits on a module using Dang SDK to test the behavior when we are installing multiple versions of the same module. They are affected by the Zig issue so tests are failing.

The fix is here just to use a different test module that has two different versions not impacted by the Zig issue. The module content itself doesn't matter.

vivid lintelBOT
ornate vigilBOT
#

Having intermittent issues after publishing a container with dagger-in-dagger.

The following (approximate) code is being executed in a process within dagger:

async def build(destination: str) -> str:
    async with dagger.connection():
        return (
            await dag.container()
            .from_("alpine:latest")
	    # ... more layers added
            .with_registry_auth(...)
            .publish(destination)
        )

The progress output indicates...

ornate vigilBOT
vivid lintelBOT
#

Summary

Thanks to the Workspace API, modules can discover dynamic sets of related objects — tests by name, packages by path, services by label — but can't present them to clients without losing features like check, generate, keyed selection, and batching.

Collections fix this. Annotate a module type with @collection / +collection, and the engine projects it into a public type with standard operations: keys, list, get, subset,...

vivid lintelBOT
#

The current Dagger Shell documentation claims full support for Bash features such as variables: https://github.com/dagger/dagger/blob/db59252ad0fb2ff7f9c7b3be78b970876ad97b4c/docs/current_docs/introduction/features/shell.mdx?plain=1#L53

However, actually trying to use such features, say variable slicing, results in the following error:

$ echo 'X=abc; echo ${X:1}' | bash
bc
$ echo 'X=abc; .echo ${X:1}' | dagger shell
...
Error: -:1:17: slicing is a bash/mksh feature; tried parsing as p...
ornate vigilBOT
#

Sorry, I was replying by email. Github put my replies in separate threads for some reason :facepalm:

Creating a small reproducer for this is proving troublesome. The issue is intermittent, and small changes seem to cause it to happen less or not at all. Then sometimes it just works repeatedly, making it very difficult to work out what's actually safe to remove from the reproducer!

The failure mode is also a 5 minute timeout expiring, so automating the reduction is also a nightmare.

ornate vigilBOT
ornate vigilBOT
#

Right now it's not failing at all. It was failing pretty repeatedly this morning, but hasn't failed this afternoon.

A question here is whether dagger is attempting to talk to some cloud service and is failing to do so? Would explain the weirdness here.

For example, I know that on the end of every dagger run it tells me whether there's a new version of dagger. To find that out it must be querying some remote server. How can I turn all of that off?

#

For example, I know that on the end of every dagger run it tells me whether there's a new version of dagger. To find that out it must be querying some remote server. How can I turn all of that off?

It doesn't seem this is the issue. If you're seeing an issue from the python code it seems to me that something in the python side is somehow setting a 5m timeout somewhere. Let me run a somehing really quick here and I'll come back to you

ornate vigilBOT
vivid lintelBOT
vivid lintelBOT
ornate vigilBOT
#

I ran our pipeline every 15 minutes overnight, and that generated this failure mode several times. It also succeeded many times as well. Flakey!

I've extracted the relevant section of the engine log: log-redacted.txt

For synchronisation purposes, the timeout exception occurred at 04:55:08

43  : [5m8s] | subprocess.TimeoutExpired: Command '['/root/.cache/dagger/dagger-0.20.3', 'session', '--label', 'dagger.io/...
vivid lintelBOT
vivid lintelBOT
#

Modules v2 redesigns, in a backwards-compatible way, how Dagger modules are developed, configured, and operated.

Module developers don't have enough control over their user's workspace. End users are exposed to too much complexity. Modules v2 addresses both: more powerful APIs for module developers, a simpler experience for end users.

This PR contains the design specs and their rollout sequence:

Spec Description PR
[Overview](https://github.com/dagger/dagger/b...
vivid lintelBOT
#

When running dagger call from two different git worktrees simultaneously against the same engine daemon, the content-digest cache in dagql could return a Module from a different session. That Module carries a path-dependent ContextDirectoryPath from the wrong worktree, causing "module not found" errors.

Scope the asModule resolver with CachePerSession so each session gets its own result, preventing the content-digest cache from leaking path-dependent state across sessions.

vivid lintelBOT
#

Summary

Add a non-secret companion to withSecretVariable:

type Container {
  withVolatileVariable(name: String!, value: String!): Container!
  withoutVolatileVariable(name: String!): Container!
}

withVolatileVariable(name, value) sets a non-secret env var for future withExec calls on that container. Changing only its value does not invalidate cached withExec results. If the exec reruns for some other reason, it sees the latest volatile value.

Warning

`withVol...

vivid lintelBOT
#

Refs #12902

Summary

  • add withVolatileVariable / withoutVolatileVariable to Container
  • make volatile vars visible only to future withExec calls
  • exclude volatile values from exec cache invalidation while keeping normal env/secret behavior intact
  • document the feature and its cache-safety caveats

Verification

  • GOOS=linux GOARCH=arm64 go test -c -o /tmp/core-schema.test ./core/schema
  • GOOS=linux GOARCH=arm64 go test -c -o /tmp/core-integration.test ./core/integration
  • ...
vivid lintelBOT
#

Proposal

Add ToolPipe MCP Server integration to provide 120+ developer utility tools within dagger CI/CD workflows.

Relevant Tools

  • Docker Compose Generation: Generate Docker Compose configs
  • GitHub Actions Workflow Generation: Create CI workflow files
  • Nginx Config Generation: Generate reverse proxy configs
  • Code Minification: Minify JS/CSS/HTML for build steps
  • JSON/YAML/XML Conversion: Transform config formats
  • Hash Generation: Verify artifact integri...
vivid lintelBOT
#

Feature Request: MCP (Model Context Protocol) Integration

Problem

AI-powered development tools (Claude, Cursor, Windsurf, Cline, VS Code Copilot) are increasingly used alongside dagger. Currently there's no standardized way for AI agents to interact with dagger's functionality programmatically via the Model Context Protocol.

Proposal

Add MCP server support to dagger, enabling AI agents to:

  • Discover and invoke dagger's core features as MCP tools
  • Integrate with AI-powered I...
vivid lintelBOT
#

Summary

Fix YAML indentation of name under secretRef in the engine StatefulSet template.

Problem

When magicache.enabled: true, the rendered envFrom block was invalid:

envFrom:
  - secretRef:      # empty object
    name: foo       # sibling instead of child

Kubernetes rejected the pod with:

spec.containers[0].envFrom: Invalid value: "": must specify one of: configMapRef or secretRef

Fix

Indent name two additional spaces so it is cor...

vivid lintelBOT
ornate vigilBOT
vivid lintelBOT
#

Bumps the sdk-java group in /sdk/java with 3 updates: io.smallrye:smallrye-graphql-client-api, io.smallrye:smallrye-graphql-client-implementation-vertx and com.palantir.javapoet:javapoet.

Updates io.smallrye:smallrye-graphql-client-api from 2.17.0 to 2.18.0

Updates io.smallrye:smallrye-graphql-client-implementation-vertx from 2.17.0 to 2.18.0

Updates io.smallrye:smallrye-graphql-client-implementation-vertx from 2.17.0 to 2.18.0

Updates `com.pa...

#

Bumps the sdk-python-docker group with 1 update in the /modules/ruff/build directory: astral-sh/ruff.

Updates astral-sh/ruff from 0.15.8 to 0.15.9

Release notes
Sourced from astral-sh/ruff's releases.

0.15.9
Release Notes
Released on 2026-04-02.
Preview features

[pyflakes] Flag annotated variable redeclarations as F811 in preview mode (#24244)
[ruff] Allow dunder-named assignments in non-strict mode for RUF067 (#24089)

Bug fixes

[flake8-errmsg] Avo...

ornate vigilBOT
#

I think dagger can be used to support AI agent sandboxing use cases by opening up to support more than just runc i.e. firecracker, gvisor, potentially smolvm (disclaimer: I am working on smolvm).

The idea is to have a more isolated runtime than pure containers and/or more optimized runtimes.

I think this is feasible generally just based on read on the codebase + ai to help me understand so please correct me if I am wrong.

Generally a worker implements an executor (which is interface...

ornate vigilBOT
vivid lintelBOT
#

Fix dagger up related tests.
The main issue on TestUpPartialStartupFailure was a wrong port on the service that should have been healthy, ended up in a timeout.

I also added an env variable on PortCollision test to avoid both services to return the same instance from the engine deduplication.

ornate vigilBOT
vivid lintelBOT
#

Add support for the @up directive in the Dang SDK, matching the existing +up (Go), @up() (TypeScript), @up (Python), and @Up (Java) annotations.

  • Declare @up in the coreDirectives schema (dagql/server.go) so the Dang parser accepts it
  • Handle case "up" in the directive switch in dang_op.go to emit the withUp dagql selector during module registration
  • Add hello-with-services-dang test fixture with web, redis, and nested infra:database services
  • Add Dang to TestUpDirectSDK and TestUpA...
vivid lintelBOT
#

Add a @cached GraphQL directive with policy (FunctionCachePolicy enum) and ttl (optional String) args, enabling SDK-level cache control annotations.

Changes

dagql/server.go — Move module-specific directives (@sourceMap, @enumValue, @defaultPath, @defaultAddress, @ignorePatterns, @check, @generate) out of coreDirectives, keeping only @deprecated and @experimental (true GraphQL-level concerns).

core/schema/module.go — New moduleDirectives instal...

vivid lintelBOT
#

Summary

This guide provides comprehensive best practices for CI caching with Dagger, addressing common pain points developers face when optimizing their CI/CD pipelines.

What This Guide Covers

  • Overview of CI caching concepts and benefits when using Dagger
  • Step-by-step instructions for implementing effective caching strategies
  • Common pitfalls and how to avoid them
  • Performance optimization techniques

Why It's Useful

CI caching is one of the most common pain points for team...

ornate vigilBOT
ornate vigilBOT
#

Bit old but still relevant, I'm in favour of removing it.

Additional arguments to remove:

  • It's outdated, it recommends using a graphql library that hasn't seen a commit in 5 years. (We swapped to our own fork to fix bugs and modernize it).
    • We could update it, but honestly, I have no interest in this functionality nor in writing docs for it.
  • I don't use that functionality at all, so I can't troubleshoot for confused users (other than to recommend they use the SDK instead).
vivid lintelBOT
#

Currently we have one single function in .dagger main module that runs all the generate functions and ensure the result is empty.
Those changes handle that in the engine: all generate functions are now automatically handled as a check function. When they are run, it will succeed if the resulting changeset is empty.

This allows to always ensure all generated functions are correctly run on CI, without to introduce a new module or concept.
Just declare your checks and generates and bo...

vivid lintelBOT
vivid lintelBOT
#

Hello, just a pull request to modify the documentation. I found myself in the same situation as the user who opened issue #35 (in dagger/nix repository), there's no reference to Nix in the official documentation.

I propose adding Nix as a supported installation method in the documentation.

  • New "Nix" tab in the stable releases section with Flake and NUR options
  • Update and uninstall instructions
vivid lintelBOT
ornate vigilBOT
#

Problem

We've assumed that +generate is for files that are meant to be committed. But that assumption was never enforced. Users can, and do, use dagger generate for files they don't commit — for example, protobuf-generated Go sources.

We are introducing a new feature: every +generate function is automatically loaded as a check, where a non-empty changeset causes a failure. This enforces the assumption for the first time, and will break dagger generate for users who generate u...

vivid lintelBOT
#

Summary

  • When a client connects from a subdirectory within a workspace, toolchain/blueprint source paths from dagger.json were resolved relative to the client's CWD instead of the config file location
  • Introduces resolveConfigRef that resolves relative to moduleDir for toolchains and blueprints, while keeping resolveLocalRef for the implicit module (whose path is already CWD-relative)
  • Adds a regression test that calls detectAndLoadWorkspace with a subdirectory CWD and verifi...
ornate vigilBOT
vivid lintelBOT
#

The tuist bump (83529b0cb) changed FinalRender to use fe.tui.RenderLines(), which goes through the component tree's Render() method. However, Render() has a guard that returns early when fe.quitting is true — and quitting is always true by the time FinalRender runs, since handleDone/handleEOF set it before closing the quit channel.

This caused the entire TUI progress output (checkmarks, error details, trace tree) to silently disappear on command failure, producing zero stderr output.

Fi...

vivid lintelBOT
#

What is the issue?

With _EXPERIMENTAL_DAGGER_RUNNER_HOST set to container+podman://my-dagger-engine, and podman installed on the host, we see:

1   : connect
1   : [0.0s] | cloud url=https://dagger.cloud/traces/setup
2   : ┆ starting engine
3   : ┆ ┆ moby.buildkit.v1.Control/Info
3   : ┆ ┆ moby.buildkit.v1.Control/Info ERROR [0.0s]
3   : ┆ ┆ ! connection error: desc = "transport: Error while dialing: exec: \"docker\": executable file not found in $PATH"
4   : ┆ ┆ moby.buildkit.v1...
ornate vigilBOT
#

I'm not entirely sure to like this approach, but let me explain why.

The check-generate relationship makes sense. We have a function to generate something and the counterpart is a check function that ensures the files are generated. But this only works if they are aligned:

  • if the generate function has been run, the check function must pass. And a subsequent call to generate must have no effect
  • if the check function doesn't pass, to run the generate function must fix it and ...
ornate vigilBOT
#

With 1. we say that the state on which we will run the check function is the one containing the generate result. With 2. we are breaking the check-generate relation: the check can pass, it doesn't mean a generate call will produce an empty result.

Not sure I get this. My impression is that the generate function can always return all files, and then check further filters them out against existing ones. And in the 2nd scenario would simply filter out based on .gitignore.

...

#

My impression is that the generate function can always return all files, and then check further filters them out against existing ones. And in the 2nd scenario would simply filter out based on .gitignore.

Yes, but it breaks the cycle between generate and check.
If a file is ignored by the check it means it can be there or not it will have no impact. So check cannot validate generate is needed. And that's the purpose of the check here, to know that a generate call is required.

ornate vigilBOT
#

Yes, but it breaks the cycle between generate and check. If a file is ignored by the check it means it can be there or not it will have no impact. So check cannot validate generate is needed. And that's the purpose of the check here, to know that a generate call is required.

If files are not source-controlled, that typically means they are intermediary build artifacts and will be validated eventually by a compiler or something else.
You're right, the generate check by itself can't do th...

vivid lintelBOT
vivid lintelBOT
#

Summary

  • Fixes #12938
  • When loading the outer .env file, scope the Host.directory() call with an include filter so only the .env file is uploaded, not the entire parent directory.

Test plan

  • [ ] Verify that invoking a module from a directory with a large sibling (e.g. home dir) no longer uploads everything when a .env exists
  • [ ] Confirm .env loading still works as expected

🤖 Generated with Claude Code

vivid lintelBOT
#

Summary

  • Switch all in-repo modules from the external github.com/vito/dang/dagger-sdk@8eba69d6... SDK source to the built-in dang SDK shorthand.
  • Touches dagger.json for codegen, cmd-test fixture, evals object-fields fixture, and the toolchains (changelog, ci, dotnet/elixir/go/java/typescript SDK dev, security, test-split).

Test plan

  • [ ] Confirm modules still load and codegen against the built-in dang SDK in CI.
vivid lintelBOT
#

Module.checks().list() now returns only the primary module's own checks; checks contributed by installed toolchains are silently missing.

How to reproduce

In any module that installs a toolchain contributing checks (e.g. the Go toolchain's go:lint):

# A: via workspace
dagger check -l

# B: via module source
dagger query <<'GQL'
{
  moduleSource(refString: ".") {
    asModule { checks { list { name } } }
  }
}
GQL

Expected

A and B return the same set of checks.

Act...

#

Summary

  • add hidden dagger session --workspace/-W plumbing on the session path only
  • add dagger.WithWorkspace(ref) and forward it to spawned Go SDK sessions
  • reject workspace overrides when attaching to an existing session
  • expose the option to generated Go clients

Testing

  • go test ./engineconn in sdk/go
  • go test . -run ^TestWithWorkspace$ in sdk/go
  • dagger call engine-dev test --pkg=./core/integration --run=TestSession(CmdWorkspaceFlag|ClientParamsWorkspace)$ (in ...
vivid lintelBOT
#

Follow-up to #12936 — adds an integration test so the final render can't silently disappear again.

Problem

#12936 fixed a regression introduced by the tuist bump (#12874): on a failed dagger call under an interactive TTY, frontendPretty.FinalRender was silently dropping everything because Render() early-returned on fe.quitting. The user was left with an empty terminal after a failure.

The fix landed with no test, which is how the regression slipped in to begin with — the existi...

vivid lintelBOT
#

Expose the Service produced by a +up-tagged module function as a new schema field on Up (asService) and a list on UpGroup (asServices). Both reuse ModTreeNode.DagqlValue for evaluation, so the returned Services carry the original user-function dagql ID and share cache identity with direct function invocations.

This lets callers of workspace.services() (and similar APIs that return UpGroup) access the underlying Services directly, without having to run them via Up.run / UpGroup.run.

Inte...

vivid lintelBOT
#

compareDirectories and friends set cmd.Dir = oldDir to avoid inheriting
the caller's cwd, with the stated intent of avoiding a broken worktree
.git file. That only half-works: the mitigation assumes oldDir itself is
free of any broken .git — but when the mounted buildkit refs come from a
git worktree, every mount has a .git FILE at its root carrying a host-
absolute "gitdir:" path that doesn't exist inside the buildkit session.
Git's repository discovery walks cwd, finds that .git file,...

vivid lintelBOT
#

reparentWorkspaceTreeRoot was unconditionally wrapping every primary workspace module's tree root with a synthetic parent named after the module, so every check/generator/service path was rendered as : — including the workspace's own root module.

As a result, dagger check -l on this repo showed dagger-dev:generated instead of just generated, contradicting the documented behavior (docs/current_docs/introduction/core-concepts/checks.mdx) where only toolchain items are namespaced. T...

vivid lintelBOT
#

Summary

When loading a Go module, a Go package/type error can cause the module to be silently omitted from the served schema instead of failing load.

Repro

  1. dagger init --sdk=go --source=. --name=minimal
  2. Introduce a Go error, for example:
package main

type Minimal struct {
  1. Run dagger functions (or otherwise load the workspace module).

Actual

The module is silently ignored/dropped on load.

Expected

Module load should fail and surface the underlyi...

#

Summary

toolchains[].ignoreGenerators no longer affects dagger generate.

The field still exists in dagger.json schema and config parsing, but current workspace-based generator loading does not consume it, so ignored generators are still listed and still run.

Current behavior

Given a module with a toolchain entry like:

{
  "toolchains": [
    {
      "name": "hello-with-generators",
      "source": "../hello-with-generators",
      "ignoreGenerators": [
        "genera...
#

Summary

Workspace.generators().isEmpty() returns true on a fresh GeneratorGroup even when the selected generators would produce non-empty changes.

This appears to be a server-side bug in GeneratorGroup.isEmpty, not a workspace include/filtering issue.

Repro

Use any module with a generator that returns a non-empty Changeset, for example [core/integration/testdata/generators/hello-with-generators](https://github.com/dagger/dagger/blob/main/core/integration/testdata/generat...

#

Summary

  • fail Go module type loading when go/packages reports package errors
  • surface the real Go error instead of silently dropping the module from the workspace schema
  • add documented regressions for both the low-level loader and the CLI module-load path

Closes #12952.

Verification

  • go test ./cmd/codegen/generator/go -run TestLoadPackageFailsOnPackageErrors -count=1
  • `GOCACHE=/tmp/go-build-cache GOOS=linux GOARCH=amd64 go test -c ./core/integration -o /tmp/core-integration-...
vivid lintelBOT
#

Summary

  • require run() before reading generator changes or isEmpty
  • add explicit GraphQL resolvers so pre-run reads fail clearly for single generators and groups
  • cover the contract with integration tests and update the schema docs

Testing

  • dagger --progress=plain call -m ./toolchains/engine-dev test --pkg=./core/integration --run='TestGenerators/TestGeneratorResultFieldsRequireRun' --test-verbose
  • `dagger --progress=plain call -m ./toolchains/engine-dev test --pkg=./core/...
vivid lintelBOT
#

I can reproduce a dagger generate failure for a valid local module:

Error: compute their paths: exit status 128

This reproduces with both builtin dang and the external dang SDK, so it does not appear to be dang-specific.

Minimal module:

dagger.json

{
  "name": "repro",
  "engineVersion": "v0.20.3",
  "sdk": {
    "source": "dang"
  }
}

main.dang

type Repro {
  let source: Directory! @defaultPath(path: "/")

  pub scaffold: Changeset! @generate ...
vivid lintelBOT
#

Fixes #12956 and supersedes #12961 and #12959

Background

Locally we saw:

  • dagger -c 'current-workspace | generators | run' takes ~10 minutes (it runs every toolchain generator in the workspace).
  • dagger check generated on the same workspace finishes in seconds (no generators ran).

That told us the CLI session and the .dagger check were seeing different module lists. Tracing currentWorkspace().generators() in both contexts revealed the discrepancy:

  • The CLI call r...
vivid lintelBOT
#

Hi team! 👋\n\nThis PR addresses the documentation inconsistency raised in #12893.\n\nProblem\nThe current shell docs claim that "all the features of the Bash syntax are available in Dagger Shell". However, the underlying parser is configured with syntax.LangPOSIX (introduced in #8996), which means Bash-specific extensions like variable slicing or the [ builtin are not actually supported.\n\nChange\n- Replaced the "full Bash" wording with a more accurate description: Dagger Shell a...

vivid lintelBOT
#

Bumps the sdk-java group in /sdk/java with 1 update: io.opentelemetry:opentelemetry-bom.

Updates io.opentelemetry:opentelemetry-bom from 1.60.1 to 1.61.0

Release notes
Sourced from io.opentelemetry:opentelemetry-bom's releases.

Version 1.61.0
API

Stabilize isEnabled() on Tracer, Logger, and metric instruments (#8200)

Incubating

BREAKING Update EnvironmentGetter and EnvironmentSetter key normalization to reflect spec changes (#823...

#

Bumps the sdk-elixir group in /sdk/elixir with 1 update: credo.

Updates credo from 1.7.17 to 1.7.18

Release notes
Sourced from credo's releases.

v1.7.18
Check it out on Hex: https://hex.pm/packages/credo/1.7.18

Fix compatibility & compiler warnings with Elixir 1.20.0-rc.4
Fix problem with transitive deps in umbrella apps
Credo.Check.Warning.UnusedMapOperation fix false positives

Changelog
Sourced from credo's changelog.

1.7.18

Fix compatibili...

#

Bumps the sdk-python-docker group with 1 update in the /modules/ruff/build directory: astral-sh/ruff.

Updates astral-sh/ruff from 0.15.9 to 0.15.10

Release notes
Sourced from astral-sh/ruff's releases.

0.15.10
Release Notes
Released on 2026-04-09.
Preview features

[flake8-logging] Allow closures in except handlers (LOG004) (#24464)
[flake8-self] Make SLF diagnostics robust to non-self-named variables (#24281)
[flake8-simplify] Make the fix for collap...

vivid lintelBOT
#

Problem

Workspace.path currently returns a path relative to the workspace boundary, such as "." or "app/frontend".

That is inconsistent with the rest of the Workspace API:

  • workspace.directory("/foo") and workspace.file("/foo") interpret paths with a leading / from the workspace boundary
  • relative paths are interpreted from the workspace directory
  • workspace.findUp(...) already returns paths with a leading /

As a result, Workspace.path is easy to misuse. A caller ...

vivid lintelBOT
#

Summary

A module using builtin sdk: "dang" does not behave consistently when calling dependency modules.

In a minimal repro on v0.20.5:

  • builtin dang parent -> builtin dang child: works
  • builtin dang parent -> external dang child: works
  • builtin dang parent -> Python child: works
  • builtin dang parent -> Go child: fails
  • builtin dang parent -> TypeScript child: fails

Both failures time out while loading the child module runtime.

This is the same failure shape I ...

vivid lintelBOT
#

Summary

  • fall back to the parent caller when a synthetic nested client has no session attachable of its own
  • preserve the current-client attachable when one does exist
  • add regression coverage for builtin dang modules depending on go, python, typescript, and dang children

Fixes #12974.

Testing

env -u DAGGER_CLOUD_ENGINE -u DAGGER_CLOUD_TOKEN -u DAGGER_CLOUD_URL dagger --progress plain call -m ./toolchains/go test --pkgs ./engine/server --run "TestResolveClientCaller|TestEnsur...
vivid lintelBOT
#

Summary

  • Add a new reusable markdown-lint module under modules/markdownlint
  • Install it for our own repo's use
  • Remove the broken markdownlint check from the project-specific docs-dev toolchain
  • Fix existing markdown lint violations across the repo

Test plan

  • [ ] Verify dagger call on the markdown-lint module works
  • [ ] Confirm docs-dev toolchain still builds without the removed check

🤖 Generated with Claude Code

vivid lintelBOT
#

The elixir-sdk-dev toolchain module is creating a container in which tests will be run.
It ended up with a weird issue where the source directory of the elixir SDK is not found. Instead of looking for /sdk/elixir it tries to find /sdk/elixir/sdk/elixir.

The path of the directory is relative to the root of the workspace (the root of our git repository). But the way this directory is mounted, the root is not correctly computed (the contextDirPath).

The contextDirPath is computed ...

ornate vigilBOT
vivid lintelBOT
#

What is the issue?

When we connect to dagger and specify a remote workspace (pointing to a git repository) the resolution of directories is not made correctly.

For instance, let's say we are looking for the repository /helm/dagger, it will says it load currentWorkspace.directory(path: "/helm/dagger") which makes sense. The directory can be used, mounted, accessed. But the files will be the ones from the root, like if it was currentWorkspace.directory(path: "/").

Dagger versio...

vivid lintelBOT
#

The Workspace.directory DagOp wrapper defaulted its filename to "/", which overrode the Dir on the Directory returned by resolveRootfs. For remote workspaces without filters, resolveRootfs selects the subpath via Directory.directory (which updates Dir but not LLB), so the subpath was lost once the DagOp ran and evaluated the full rootfs LLB. Downstream consumers (WithDirectory, Entries, content hashing) then saw the repo root instead of the requested subdirectory.

Pass a WithPathFn to the ...

vivid lintelBOT
#

Problem

When a module accesses a path that is absolute (starts with /), either via +defaultPath in the module's context directory or via Workspace.Directory()/Workspace.File() in the workspace API, the same logic is used (in two different code paths) to detect the "boundary" from which to resolve the absolute path:

  1. Find-up a git root (directory containing .git). If found, that's the boundary.
  2. Fall back to the workspace directory (Workspace API) or the module's context dir...
#

Problem

Since workspace: plumbing & compat, the engine auto-loads modules from the current workspace by default. That means a client that never explicitly loads modules can still have its schema changed based on its current working directory.

This is especially dangerous when an auto-loaded module is served with entrypoint: true and defines a function that conflicts with a core Query field. In that case, a plain core API call can silently ...

vivid lintelBOT
#

Summary

  • add LoadWorkspaceModules as the opt-in session/client flag and normalize the legacy SkipWorkspaceModules input at the boundary
  • change the engine default so plain connections expose only the core API unless workspace module loading is explicitly requested
  • update CLI and SDK entry points that intentionally depend on workspace modules to opt in explicitly

Closes #12982.

Verification

  • gofmt -w on touched Go files
  • GOCACHE=/tmp/dagger-go-build go test ./engine
  • `GO...
vivid lintelBOT
vivid lintelBOT
#

Summary

  • Auto-promote the -m remote git ref to the workspace in loadWorkspaceFromHostPath when CWD has no workspace markers (no .git or dagger.json going up). Without this, dagger -m github.com/dagger/dagger@main check java-sdk:lint from a non-workspace directory resolves the toolchain's defaultPath="/" workspace arg against the empty CWD and can't find files that only exist in the remote repo.
  • Adds ModuleSuite.TestRemoteWorkspaceToolchainDefaultPath with two subtests — `e...
vivid lintelBOT
#

This is a follow-up to #12985 to make the tests introduced in the PR more resilient.

Replace the external dagger-test-modules dependency with an inline fixture. The test now:

  1. Scaffolds the workspace (root dagger.json + greeter toolchain + target-subdir/maven/hello.txt) directly inside a goGitBase container via dagger init / toolchain install, and commits it.
  2. Pushes the commit into a bare repo at /srv/repo.git in the same container.
  3. Serves /srv over smart-HTTP via gitSma...
ornate vigilBOT
#

Hello,

re: "Docker API compatibility bridge", aka Dogger. The (limited) work I've done on it is here. [...] The primary use-case that I had in mind was kind.

I have exactly that use case, I maintain a cli helper to start kind with batteries included https://github.com/clk-project/clk_extension_k8s

And I run my tests using earthly with dind https://github.com/clk-project/clk_extension_k8s/blob/master/Earthfile#L72

I lov...

vivid lintelBOT
#

Problem

Our CI bootstrap check doesn't exercise enough of our own CI to catch real breakages. We've hit situations where all tests pass, but upgrading Dagger to run its own CI fails — because our CI is a particularly complex use case (multiple layers of dagger-in-dagger nesting, etc.) that the bootstrap check doesn't cover.

Solution

Expand the bootstrap check to cover more of our CI pipeline — enough to catch these regressions, but not the full suite (since bootstrap runs everything ...

vivid lintelBOT
vivid lintelBOT
#

Summary

  • add typescript-sdk:test-nodejs-lts to the default ci:bootstrap check set
  • keep the existing lint coverage in place
  • document inline why this specific check is included

Why

Bootstrap already verifies that a fresh engine and CLI can run Dagger's own checks. The gap is the default inner check selection. typescript-sdk:test-nodejs-lts adds downstream coverage for the provisioned CLI path without dragging in a large SDK matrix.

Closes #12987.

Verification

  • `dagger ch...
vivid lintelBOT
#

Re-add toolchain modules to loadDependencyModules so a module's generated SDK bindings expose toolchain types — restoring the v0.20.3 behavior that was removed in the workspace refactor (db59252ad / 70bf9851b).

Without this, a module that installs a toolchain cannot reference the toolchain's types from its own code: dagger develop produces bindings with no constructor for the toolchain, so code like dag.MyToolchain() fails to compile with 'dag.MyToolchain undefined'. Runtime is already cov...

vivid lintelBOT
#

Backed PHP enums referenced in module function signatures are now auto-discovered and registered against the engine — no annotation needed, matching Go and TypeScript SDK behavior.

Previously, if a module function took or returned a backed enum, the engine never learned about its values and the call would fail. The runtime decoding side (DecodesValue) was already half-wired via ::from(), but registration was completely missing.

What changed:

  • FindsDaggerEnums walks the type-grap...
vivid lintelBOT
#

Summary

  • Workspace.path now returns paths with a leading / (e.g. /app/frontend instead of app/frontend, / instead of .)
  • Aligns with the rest of the Workspace API which already uses leading-slash paths

Changes

  • engine/server/session_workspaces.go: use path.Join("/", detected.Path) when setting core.Workspace.Path
  • core/workspace.go: update field doc to reflect the new format

Closes #12970

Test plan

  • [x] TestLocalWorkspaceAddress passes (Docker, Go 1.25, ...
vivid lintelBOT
vivid lintelBOT
#

Problem

Testing the next release of Dagger requires manually building from source or running the install script with special env vars:

curl -fsSL https://dl.dagger.io/dagger/install.sh | DAGGER_COMMIT=HEAD BIN_DIR=/tmp/dagger-dev sh

This is too much friction for users who want to quickly try the latest from main — whether to test a fix, preview a feature, or verify a regression.

Solution

Add a --next flag to the CLI:

dagger --next call foo

This re-executes the rest of t...

vivid lintelBOT
#

Improve our Go linter module:

  • dagger call go lint-module --module=...: previously the argument was mod, and --mod was conflicting with the -m/--mod of dagger CLI
  • dagger call go lint --limit=1: allow to set the parallelism limit for golangci-lint, very useful on personal machines to not use all the resources
vivid lintelBOT
#

this follows the same approach images like dind follow (https://github.com/docker-library/docker/blob/5b2346972dda13a30a936507fd11696296a527ea/29/dind/dockerd-entrypoint.sh#L148) where the entrypoint is wrapped with docker-init after cgroups are correctly set. In addition to that, having the init binary in the image makes this change more consistent since it's no longer dependent on the engine provisioner

vivid lintelBOT
#

Previously, codegen for list-of-objects fields returned a single-element Vec wrapping a shared selection, which produced incorrect results at runtime. Generate an async method that selects the ids, executes the query, and reloads each entry via the root load_*_from_id helper. Also teach the query unpacker to unwrap arrays of single-key objects so the id list deserializes correctly.

vivid lintelBOT
vivid lintelBOT
vivid lintelBOT
#

What

Adds a new docs page — "Persisting Artifacts to the Caller's Filesystem" — and a warning admonition on return-types.mdx, clarifying that File.export / Directory.export behave differently inside a @func body vs in a CLI chain.

Why

Users who reasonably assume file.export("/some/path") writes to their pod or laptop filesystem get silent data loss: the write succeeds into the module runtime container, which is then torn down with no error.

Hit this in production: ...

vivid lintelBOT
#

Summary

Re-apply the fix from #12975 (reverted in b30af043d) on top of the
egraph merge (#11856), which reshaped engine/server/session.go
enough that the original patch no longer applied cleanly.

Background

When a module uses the builtin dang SDK and depends on other modules
(go / python / typescript / dang), loading those dependencies fails.

Internally, evaluating a builtin dang module spawns a synthetic
nested client
. Unlike a "real" client, a synthetic client does not
est...

vivid lintelBOT
#

What happened? What did you expect to happen?

My Build is showing this:

WARNING [opentelemetry.exporter.otlp.proto.http.metric_exporter]: Transient error Internal Server Error encountered while exporting metrics batch, retrying in 0.84s.
WARNING [opentelemetry.exporter.otlp.proto.http.metric_exporter]: Transient error Internal Server Error encountered while exporting metrics batch, retrying in 1.65s.
WARNING [opentelemetry.exporter.otlp.proto.http.metric_exporter]: Transient error Inter...

vivid lintelBOT
#

Bumps the sdk-python-docker group with 1 update in the /modules/ruff/build directory: astral-sh/ruff.

Updates astral-sh/ruff from 0.15.10 to 0.15.11

Release notes
Sourced from astral-sh/ruff's releases.

0.15.11
Release Notes
Released on 2026-04-16.
Preview features

[ruff] Ignore RUF029 when function is decorated with asynccontextmanager (#24642)
[airflow] Implement airflow-xcom-pull-in-template-string (AIR201) (#23583)
[flake8-bandit] Fix S103 false ...

vivid lintelBOT
#

When a module has a constructor with arguments and is used as a workspace
entrypoint, the engine installs a synthetic with field on Query to carry
those args through. It's plumbing — users don't call it, the CLI reads its
args to build root flags — but until now it showed up in dagger functions
right next to their real functions.

This adds a Hidden flag to DagQL FieldSpec and core.Function, surfaced
as a new @hidden directive. Hidden fields stay callable and stay in
introspecti...

vivid lintelBOT
#

Fixes #13008.

What you were seeing

Starting a Python Dagger module produces a stream of warnings and an ~8s stall per invocation:

WARNING [opentelemetry.exporter.otlp.proto.http.metric_exporter]: Transient error Internal Server Error encountered while exporting metrics batch, retrying in 0.84s.
WARNING [...] retrying in 1.65s.
WARNING [...] retrying in 3.82s.
ERROR [...] Failed to export metrics batch due to timeout, max retries or shutdown.

It happens twice per call — once whi...

vivid lintelBOT
#

I have no understanding of how dagger works and I have never used it. I was browsing through the documentation to better understand what dagger is and whether its a good fit for my project, I found this weird thing on the docs that tripped me off. At first, I thought it meant that I had to have a persistent Dagger Engine running somewhere else, which would make this not a good fit for me. I didn't give up and as I was learning more, I think this might have been a typo, which would drastically...

vivid lintelBOT
#

Similar to Container.WithServiceBinding, this introduces Container.WithLocalhostForward which attaches a Service to a specific port on a container, available in the container at localhost:. This is convenient because wiring through a hostname in test runtimes can be a pain and aren't always easily configurable.

See ./hack/designs/localhost-binding.md for more detail.

vivid lintelBOT
#

Generic reusable modules cannot compose with each other when one module needs a running service provided by another. For example:

• A docusaurus module knows how to start a documentation site ( +up function).
• A playwright module knows how to run browser tests against a web app ( +check function that accepts a Service constructor arg).
• Both modules are installed in the same workspace, but neither is aware of the other.

Today, there is no way in workspace configuration ...

ornate vigilBOT
vivid lintelBOT
#

Problem

When you run dagger -m @, the entrypoint module may declare toolchains. Those toolchains use +defaultPath to read files from the project they're checking.

PR #12986 fixed a bug where +defaultPath was reading from the user's local directory (CWD) instead of the remote ref. But the fix is incomplete: it reads from the toolchain's own source, not from the entrypoint module's source.

This happens to work when the toolchain lives in the same repo as the entrypoint modul...

vivid lintelBOT
#

This fixes issue 13018.

A remote module can install a toolchain from another repo. The toolchain code should still load from the toolchain repo, but +defaultPath inputs should resolve from the module that installed it.

This passes a private defaultPathContextSource argument through asModule for related modules and toolchain dependencies. It also keeps the asModule cache variant separate for each defaultPath context source.

The branch includes a regression test for a remote module using a r...

vivid lintelBOT
vivid lintelBOT
#

Summary

A user reported:

Is the dagger mcp feature broken in 0.20.6. Earlier the custom functions would be available through mcp. Now this is not the case. Only dagger core is available and list tool comes back empty.

I was able to reproduce the issue. dagger mcp starts, but it does not expose the functions from the current module. Only the generic MCP tools are available.

What I Did

I used a Dagger module that has at least one custom function.

First I checked that the module ...

vivid lintelBOT
vivid lintelBOT
#

Use the shared PSScriptAnalyzer module (github.com/dagger/PsScriptAnalyzer) instead of the local copy. Delete the old one.

The old setup was a local Go module that wrapped PSScriptAnalyzer with project-specific CLI flags to exclude rules. Now we use a shared Dagger module with no project-specific glue code. To make that work, the PSReviewUnusedParameter exemption moved into install.ps1 itself via SuppressMessageAttribute, which is the idiomatic PowerShell approach anyway.

vivid lintelBOT
#

Move installer e2e tests to a native Go test runner under e2e/installers/. This replaces the project-specific toolchains/installers Dagger module, which is now deleted.

The old setup wrapped everything in a custom Dagger module with project-specific glue code. The new setup is plain go test files that call the Dagger Go SDK directly, so you get idiomatic Go tooling during development (standard test flags, IDE integration, go test ./...). Dagger is still there but used the way it's me...

vivid lintelBOT
#

This PR makes two small improvements to the Python SDK that you notice the first time you run dagger init --sdk=python or dagger develop.

Align the default Python image

Today the SDK pins its base image to Python 3.14.3, but the template pyproject.toml we drop into a new module sets requires-python = ">=3.13". The runtime reads that and asks the engine for python:3.13-slim, which is a different image from the one the SDK ships with — so a fresh init pulls both 3.13 and 3....

vivid lintelBOT
#

What & why

Today, every dagger call (and any other runtime operation) re-generates Go
bindings inside a container before building the module. That's wasted work:
the generated files rarely change between two calls, but the user pays for
codegen every time.

This PR is the Go-SDK slice of a larger effort to stop doing that. After it
merges, Go module authors can commit their generated files (dagger.gen.go,
internal/dagger/) and opt out of runtime codegen entirely. The hot path
sh...

vivid lintelBOT
vivid lintelBOT
#

What

This adds a hidden global -W, --workspace flag.

The flag sets client.Params.Workspace before the CLI connects to the engine.

dagger session --workspace still works. It now shares the same forwarding path as the global flag.

This also adds focused tests for the flag and for local workspace selection.

Why

The workspace branch has the larger workspace model.

Main can still use this small CLI feature now.

Keeping the flag hidden avoids making it part of the visible CLI su...

vivid lintelBOT
#

Move Helm chart e2e tests to a native Go test runner under e2e/helm/. This replaces the project-specific toolchains/helm-dev Dagger module, which is now deleted.

The old setup mixed chart checks, K3S helper code, and release-only Helm helpers into one custom module. The new setup is plain go test files that call the Dagger Go SDK directly, so Helm chart validation gets standard Go test behavior while Dagger still provides the containerized Helm/Kubectl/K3S orchestration. Release keeps ...

vivid lintelBOT
vivid lintelBOT
#

What are you trying to do?

I'd like for the kube-pod:// engine client driver to support dynamic engine provisioning akin to the image(+):// drivers.

Why is this important to you?

This makes Dagger usable in more environments. In my specific case, we're using GitHub's Actions Runner Controller to run workflow Pods on Kubernetes. Allowing the client to provision its own engine Pod would make this pattern much easier.

How are you currently working around this?

We have static...

vivid lintelBOT
#

Summary

  • stop Go lint and tidy checks from regenerating Dagger runtime bindings
  • add a generateDaggerRuntimes entrypoint that returns a Changeset using the existing Go module/runtime plumbing
  • check in the generated runtime bindings needed by affected Go modules

Verification

  • go test ./... in toolchains/go
  • dagger functions -m toolchains/go
  • dagger generate -l
  • dagger --progress=plain call go lint --include sdk/python/runtime/ --include toolchains/engine-dev/notify/ --include to...
vivid lintelBOT
#

The installer e2e test fails on arm64 because it compares equivalent platform strings literally.

dagger version prints:

linux/arm64/v8

but the test expects Container.platform():

linux/arm64

Failure:

malformed dagger version output "dagger v0.20.6 (image://registry.dagger.io/engine:v0.20.6) linux/arm64/v8": expected final field to match container platform "linux/arm64"

The test should normalize platforms before comparing them.

vivid lintelBOT
#

Restore the pre-#11856 behavior where (*Module).namespaceSourceMap records at minimum the module name when the SDK does not attach a source map to a typedef/field/argument.

When commit aa719a10d migrated source-map handling to dagql results, the synthesizing fallback was lost: the new namespaceSourceMap returns the nil sourceMap unchanged, so types/fields contributed by SDKs that don't emit source maps (dang, Java, Python, PHP, Elixir) end up in the schema without any sourceMap directive.
...

vivid lintelBOT
#

What are you trying to do?

Upgrade the four OpenTelemetry log packages that are currently pinned via replace directives in go.mod from v0.16.0 to v0.19.0:

go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => v0.16.0
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => v0.16.0
go.opentelemetry.io/otel/log                                => v0.16.0
go.opentelemetry.io/otel/sdk/log                            => v0.16.0

The require block already lists v0.17...

vivid lintelBOT
#

A PR merged for 0.20.4 impacted our ability to run Dagger modules behind our airgap PR #11826. This PR will undo the effect of that PR in the presence of DAGGER_GO_SDK_OFFLINE environment switch.

The underlying cause is the original PR created a "vanity url" for dagger resources which does not resolve through go proxy.

Before the PR, the Go codegen path was self-contained for dagger-side code:

  • The two relevant source files of dagger...
vivid lintelBOT
#

Fixes #13036.

Summary

  • parse the platform printed by dagger version and the platform returned by Container.platform() as OCI platforms
  • compare with containerd/platforms.OnlyStrict so linux/arm64 matches linux/arm64/v8 without accepting merely compatible platforms like linux/arm/v8
  • add focused regression coverage for the arm64/v8 installer output case

Verification

  • go test -run '^TestCheckDaggerVersionOutputPlatformVariant$' -count=1 from e2e/installers
  • `git dif...
vivid lintelBOT
ornate vigilBOT
#

The lockfile branch contains code under the gitSchema.ref function, which must be executed for each client, which is used to lookup pinned versions from the lockfile, or to determine which lockmode the client is running under.

The code under main, currently produces a content digest under the gitschema.git function, which causes this function to be cached on subsequent calls -- this prevents the ref function from running a second time.

The issue is the caching of the git funct...

vivid lintelBOT
#

What this adds

A "Copy page" button in the docs sidebar that exports the current Dagger docs page as clean markdown, with one-click "Open in ChatGPT", "Open in Claude", and "Open in Gemini" actions.

Why for Dagger

Dagger already ships an llms.txt plugin for whole-site AI discovery. This plugin is the complementary piece for single-page handoff: when a developer is on, say, the [Functions reference](https://...

vivid lintelBOT
#

When a toolchain customization default changes, Dagger shows the new default but calling the toolchain without passing that argument can still return a result computed with the old default.

Passing the same value explicitly works, so the problem seems specific to omitted arguments that rely on the configured default.

Repro

rm -rf /tmp/dagger-default-cache-repro
mkdir -p /tmp/dagger-default-cache-repro/tool
cd /tmp/dagger-default-cache-repro/tool
dagger init --sdk=go --name=probe
...
ornate vigilBOT
#

Thanks for the discussion 🙏

Moving the content digest out of git(...) does seem right to me, as the lockfile behavior happens later, in gitSchema.ref. So we need that path to run for each client / lock mode before deciding what a ref resolves to.

Possible fix

What prevents us for RemoteGitRef.Tree to use a separate checkout snapshot key, computed after ref resolution, from the inputs that can affect the checkout result?

From what I understand, RemoteGitRef.Tree cur...