@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.
#github-feed
1 messages · Page 21 of 1
@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 ...
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/andcore/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...
- 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
WithMountedHostDirectoryalso 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...
@jedevc yeah... I thought about the exact same name but WithErr seemed wrong to me conceptually. Still, adding a new method seems the more sensible option
same problem different solution :) #8402
Personally, I like this approach better.
Container.withError is multi-language, I personally am not a fan of adding more and more features that are SDK-specific.
See @vito's comment here: https://github.com/dagger/dagger/pull/9569#issuecomment-2657252489
We essentially need the equivalent of #9344 for those, so we can avoid marking pending states as DONE.
(opening so I don't forget about this)
Fair, but this is a problem that plagues go more specifically - in other languages, errors are generally handled by exceptions, and so are thrown all the way up. No explicit extra handling in with is required for other languages.
Actually, we may not have that extra return in TypeScript but we can't execute something in a with because the with signature doesn't ret...
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...
The PHP SDK could use integration tests. With modules created, purely for testing, to assert PHP modules work when called through dagger.
For reference: #php message
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...
Would love your thoughts on this @aluzzardi @kpenfound @grouville @sagikazarmark @marcosnils @jedevc
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.
The main (only?) API user is the CLI -- you can't call mapSecret in code unless directly using the SDK without modules.
Without the URL syntax, what would be the CLI syntax for passing a secret?
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...
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.
...
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:
- When buil...
What is the issue?
Diagrams, link to it from Quickstart
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
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...
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:
- Fields being removed/renamed
- Fields added (but we don't, see https://github.com/dagger/dagger/issues/10102)
- Fields with different type signatures
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 ...
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...
staticreturn can be nice to have too. WDYT?
@WedgeSama
I'm not sure how useful it will be but it should be fairly straight forward to support at the same time. (I hope 😰)
Do you have any use-cases in mind?
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...
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...
relates a bit to @vito's current work surrounding a frontend API https://github.com/dagger/dagger/issues/9374
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...
Thanks @Nero-F, assigned to you.
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:
...
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...
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:
--debugwould beDAGGER_DEBUG=true--progresswould beDAGGER_PROGRESS=plain--silentwould beDAGGER_SILENT=true- etc ...
Related Discord: https://discord.com/chann...
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...
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:
- [...
Implement a generic ID type that matches any specialized object ID.
This is needed for improving the Env bindings API as described in #10370
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)
As a dagger newbie.. I would love to get a fully functional dagger CLI without too much hazzle, even with the current instructions there is not a single thing that I can copy and get stuff working.. if the solution is a simple install.sh that I can run.. I will go for that.
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:
What are you trying to do?
- start Dagger enging with gpu access
- create a service that loads and LLM model and expose an OpenAI API
- create awesome agents with LLM
Why is this important to you?
Testing my agents with a standalone and private workflow
How are you currently working around this?
Nope, but @shykes told me that it should be easy to implement :)
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'm not able to reproduce the error with v0.17.0
package main
import (
"context"
)
type Test struct{}
func (m *Test) Query(ctx context.Context, query string) (string, error) {
return dag.Container().From("alpine:latest").WithExec([]string{"echo", query}).Stdout(ctx)
}
$ dagger call query --query foo
foo
Since now llm is merged on main and released, is it still relevant?
I think something like that could do the job
defmodule MyModule do
use Dagger.Mod.Object, name: "MyModule"defmodule Severity do
use Dagger.Mod.Enumdefenum [ # 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...
What is the issue?
I'm getting a panic error when trying to exit the interactive terminal.
For context I'm running a k3s cluster using this example/module.
Dagger version
dagger v0.16.3 (docker-image://registry.dagger.io/engine:v0.16.3) darwin/arm64
Steps to reproduce
Try running this example module, once the terminal is open attempt to exit by executi...
The sdk doc is not currently published, but I'll have a look at that very soon. A bit of work is needed on my side to ensure everything is ready to be published.
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...
What is the issue?
We need a section in the documentation that covers the env vars that are available to configure Dagger.
We can look for references using this search: https://github.com/search?q=repo%3Adagger%2Fdagger+os.Getenv(+language%3AGo&type=code&l=Go
From this Discord thread: https://discord.com/channels/707636530424053791/1384134172502659162
We need to document how to use Dagger in a Java custom application on this page. @eunomie I know you are all setup, do you mind tackling this issue for the docs? 🙏
dagger run java ...
Problem
When calling .install MODULE from the dagger shell, the newly installed module is not available in the same session. I have to exit and re-run the shell to use it.
Solution
Fix .install so that it loads the installed module in the same shell session.
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
...
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.
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...
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/...
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...
What is the issue?
When loading a module using the git address (e.g. dagger -m git@github.com:jasonmccallister/database-agent.git) the link in the prompt becomes a mailto link.
Dagger version
v0.18.3
Steps to reproduce
Ran dagger -m git@github.com:jasonmccallister/database-agent.git and tried to call a function ask from the module.
Log output
No response
What are you trying to do?
Some LLM providers tend to throw HTTP 429/502/503 when they're overloaded. We should have a configurable retry when one of these statuses is received
Why is this important to you?
No response
How are you currently working around this?
No response
When building a container using Directory.dockerBuild, any ports exposed in the Dockerfile will be lost when calling up on the container.
What is the issue?
The with_default_args function/feature & it's capabilities as previously mentioned in [Discord](#1090037052923453470 message) two years ago but still not mentioned/updated in docs.
What are you trying to do?
I'm playing with an interactive command in a Dagger terminal and I'd like to capture the contents of stdout when the command exits.
Something similar to RedirectStdout/Stderr in WithExec would be nice.
Why is this important to you?
No response
How are you currently working around this?
No response
@vikram-dagger It would be a great help if you can solve this. Thanks
What is the issue?
I have a lot of secrets using 1Password and it's causing dagger to spend 8 seconds fetching secrets before running the withExec command:
I ended up switching to env secrets to speed it up - after that, the 8 second withExec went down to 400ms
Dagger version
dagger v0.18.3 (docker-ima...
What are you trying to do?
I am trying to convert a large docker project and I am stuck because there doesn't appear to be a way to port the VOLUME instructions.
Why is this important to you?
See above. I am stuck without VOLUME instruction.
How are you currently working around this?
I guess I could workaround it by using the dockerfile build feature, but I would like to avoid that.
Looks like a matter of adding a new function to Container to add the relevant oci metadata. 👍
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...
I've worked around this by putting everything in my top level func which has the module as a receiver and that works for now. Not sure at this point why.
Another unwanted behavior, as soon as the sub-object (in this case Workspace.Container is automatic selected), the number of input tokens inceases from ~1k to ~8k, and it crashes on openai rate limiting. Which I guess is due to the number of functions we expose to the model.
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 ...
What is the issue?
Just saw during upgrading Dagger in my team:
Dagger version
dagger v0.18.3
Steps to reproduce
No response
Log output
No response
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...
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...
== Compilation error in file test/support/object_field.ex == ** (MatchError) no match of right hand side value: {:error, :nofile} lib/dagger/mod/object.ex:208: Dagger.Mod.Object.module?/1 (elixir 1.18.3) lib/enum.ex:4390: Enum.filter_list/2 lib/dagger/mod/object.ex:186: Dagger.Mod.Object.decoder_hint/1 test/support/object_field.ex:69: (module) ! proces...
[dagger] New discussion #12635: Add more context when engine fails to start using the docker driver.
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 ...
The MCP protocol has a new feature called Roots. It is already supported by Visual Studio Code and other clients are sure to follow. We should support it as on the server side asap.
Roots seem to be the solution to our "contextual access" problem:
- Dagger is highly contextual: different directories in the same repo can have different modules, which means a different s...
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) ...
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 ...
In daggerverse - we can use this to provide neater displays for versions that aren't tagged - the pseudoversion gives human-readable context for where a version appears in relation to others. cc @jpadams @kpenfound
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 ".
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...
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 ...
@skycaptain not sure if this will help, but I explored volume exporting a little while ago and created a small example module out of it: https://github.com/cbochs/dagger-modules/tree/main/remote-cache. There are some gotchas when trying to use images for volume export, so feel free to poke around and take what you need from that repo
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...
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...
🤔 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...
[dagger] New discussion #12647: 🐞 Number in project name causes class lookup failure with Python SDK
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
...
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...
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
What is the issue?
Dagger module does not init on MacOS Intel Chip with Java SDK
Dagger version
dagger v0.9.4
Steps to reproduce
Follow build an agent instructions for Java
Log output
No response
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...
@jedevc ☝ I think I need your comments about this issue.
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
...
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.
Dagger version
dagger v0.18.9 (docker-image://registry.dagger.io/engine:v0.18.9) windows/amd64
Steps to r...
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...
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...
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...
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...
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
- Deploy a Kubernetes Executor
- Create a dagger pipeline to push an image to private registry.
- call the pipeline in gitlab ci without specifying the ...
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...
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
```...
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...
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-...
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...
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 `...
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... |
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?...
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...
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...
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...
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...
A separate motivator for using the API instead of native code is caching
@vito also tracing 😍
@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
javaSDK 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") ...
~+1 to dag.MyModule().AlpineWorkspace() where MyModule == self~
Thinking on this more...
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...
Thank you very much! Don't take my critique as anything other than a serious look at the value at what this brings.
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...
What is the issue?
dagger session destroy command is stuck. I can't stop it with Ctrl-C.
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...
dagger session destroy isn't a dagger command. Neither is mod cache prune? I'm confused, where are you getting these commands from? To clear the cache, you can use dagger core engine local-cache prune.
Can you share some more context? How are you getting the error that you're sharing?
Thanks for looking into this. This is the original issue I was trying to work around:
▶ github.com/jpadams/daggerverse/trivy@44c178290a412483e785a436aabc46c707842a62 | scan-image alpine:latest 34.0s
Report Summary
...
Love it - I think the proxying is a small price to pay for the simplicity of keeping it a Service.
@shykes do you have a proposal for what the Network type would be? I don't remember discussing it before.
Is it related to https://github.com/dagger/dagger/issues/7426?
The main use case for grouping Services together is to allow uping them together from the command line - and essentially moving the logic from @kpenfound's proxy module into core.
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...
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:...
@dagger/docs because ghcr is an authenticated registry, we need instructions before to authenticate to it.
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...
Are you sure about this?
Good catch. You can store the index URL (for vanilla pip) in ~/.pip/pip.conf. For uv you can use separate env vars for credentials. Maven has the settings.xml.
Unfortunately, Go is the outlier here. I don't think there is another way to set credentials besides user:pass in the GOPROXY url. We can avoid it by setting GOPRIVATE.
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...
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...
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 bydagger run -v. However, I only want to show [on the c...
cc @alexcb
We're actually already very inconsistent with how we handle overwriting existing content.
- Creating a file with
WithNewFileon top of an existing file, succeedscontainer | with-new-file "foo" "" | with-new-file "foo" ""
- Creating a directory with
WithDirectoryon top of an existing file, succeedscontainer | with-new-file "foo" "" | with-directory "foo" $(directory)
- Creating a file with
WithNewFileon 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
GitRepositoryorService. We should expose this implied interface as a real int...
- Some types just make more sense as an interface! They already have multiple "backends", like
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...
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...
Sorry for the bikshedding, but I'd prefer to avoid dagger login --status. IMO, dagger login should always attempt to login, while flags should modify that behavior, not perform a different action.
I like the idea of an auth subcommand?
What simplification are you referring to? I'm not aware of anything in our code that tries to hide excludes that don't end up matching anything. The code that results in this call is here, it's just setting exclude in the Host.directory call pretty straightforwardly.
Are we sure that exclude being empty isn't just a TUI bug?
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...
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...
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 inittoday)
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
-...
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...
Live development proposal
[!NOTE]
This top-level item is kept up to date - see previous versions using by looking at the edits.
This is an mega attempt to solve #6990 - our most upvoted issue in the backlog.
It's a big issue, and there's lot of different use-cases, proposed solutions, and prototypes. This is an attempt to unbundle all this, and try and address each use case - and imp...
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
--depthof a clone, we can't do this for submodules - we always go to ...
@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.watchisn't a thing - instead, I've put it as an argument toAsService.Service.watchonly really makes sense on container services, it kind of breaks the service abstraction.- 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...
Also: how would we handle host services listening on unix sockets?
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:
- Mouse isn't restored (caused by
disableMousecalled byReleaseTerminalnot having a corresponding undo inRestoreTerminal) https://github.com/charmbracelet/bubbletea/blob/b224818d994537a25de86e2658fb9f437ea0baf4/tty.go#L41-L45- Upstream issue: https://github.com/charmbracelet/bubbletea/issues/1424
- The first key press after unbackgrounding gets ...
Dagger currently only supports UNIX based OpenSSH agent forwarding
The underlying reason is:
- The current socketStore only supports UNIX + IPSocket, no named pipes
- We query the PATH to the socket (https://github.com/dagger/dagger/blob/3dfb4eeba6308ce86f1bbdc2368247eddb08bba9/engine/client/client.go#L1149), by honoring
SSH_AUTH_SOCK. However, not all clients on Windows seem to respect ...
What is the issue?
I am using the following query and have tested both Typescript and Go modules using the documentation example and asEnum.members are always null for both.
Here is the GraphQL:
query directoryAsModule {
host {
directory(path: ".") {
name
asModule {
id
name
objects {
kind
asObject {
description
name
functions {
id
name
desc...
Ahhh, yeah, this is a very fiddly known problem.
TL;DR: the typedefs in arguments/return values are "references". They're not fully populated.
If you modify your query to:
query directoryAsModule {
host {
directory(path: ".") {
name
asModule {
id
name
objects {
kind
asObject {
description
name
functions {
id
name
description
re...
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...
Issue
The Go, Python and Typescript SDKs implicitly return Void, if no type is specified: reference
The PHP SDK demands all Dagger Functions define their return type.
Should It Be Supported?
Referring to the SDK design guidelines:
Aim for the best developer experience,...
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...
Re-opening this, since this is a legitimate issue I want to track separately.
From @marcosnils in [discord](#maintainers message):
is it me or this description in not true? https://github.com/dagger/dagger/blob/c99b557537d68b9fc662a4533f4adb7696907a43/dagql/types.go?plain=1#L212
since multiple functions in that dagql Int type like this one https://github.com/dagger/dagger/blob/c99b557537d68b9fc662a4533f4adb7696907a43/dagql/types.go?plain=1#L217-L226 are also effectively handing the case for int64...
What happened? What did you expect to happen?
Hello - is there a way to run dagger without the daemon and docker images / service? Essentially run it inline on the cli (client runtime)?
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:
- Add CLI-flag to configure pull-behavior (
always=like now,missing=only pull missing images,never=never attempt to pull base images from remote) - Reduce number of simultaneous...
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...
Sounds good to me :tada:
We already have the DAGGER_NO_NAG flag, we could reuse this 🤔 Just wanting to avoid an env var for everything.
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...
What is the issue?
Several examples in the documentation fail when using the PHP SDK.
See: https://github.com/dagger/dagger/pull/11086#discussion_r2358610881
Code
See: https://github.com/dagger/dagger/pull/11082#discussion_r2357882486
[Code](https://github.com/vikram-dagger/dagger/blob/563d746bcd437b8b1ba0b42c70cb0d0d3dec008...
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...
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.
- SIGINT (
Ctrl-C) does nothing - SIGQUIT (
Ctrl-\) usually works. It results is a segfault with a massive stack trace
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...
Ah that makes sense! I didn't actually check the error message.
So the issue was actually the CLI hang on session end, then.
Haven't experienced it lately.
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:
doFetchshould 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...
This will allow passing images from the local store into a dagger function.
#!/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...
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...
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 ...
Problem
In our quest to make our CI module faster, version stands out as a source of slowness. It takes a long time to load, every time. Main culprits are:
- Git operations
- Uploading
inputsevery time, just to compute a digest
Solution
🤷♂️
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'...
cc @jedevc @TomChv @kpenfound @matipan
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...
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...
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...
When loading a module on a remote engine, filesync can take a while. In default verbosity, that filesync is hidden from TUI, so it looks like everything is completed, and the dagger call is just hanging. You have to increase verbosity to find out that there are unfinished upload/filesync spans.
@andrestone sorry about that, there must be another source of similar errors 😕 Can you provide any cloud trace links where this is occurring? Anything additional that could help me repro exactly what you're hitting would be useful too if possible (e.g. if the code in question is open-source, a link to it, etc.)
Problem
Is there a flag to disable line numbers in the generated docs? Doesn't feel very useful to me, vs. the insane amount of churn it introduces
_Originally posted by @vito in https://github.com/dagger/dagger/pull/11311#discussion_r2470108808_
Solution
_Originally posted by @charjr in https://github.com/dagger/da...
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:
-...
FYI @jedevc @marcosnils @matipan @kpenfound
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 ...
What is the issue?
I am trying to set up a registry mirror that points to a different location for hub.docker.com. Naturally, I try to follow the docs available for configuring the Dagger engine here, but I am struggling with getting this to make sense.
I created an engine.json config in $HOME/.config/dagger/engine.json with the content below:
{
"registries": {
"docker.io": {
"mirrors": ...
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.
With the recent changes introduced by https://github.com/dagger/dagger/pull/11309, we significantly improved the performances for both Node, Deno and Bun.
So I'm wondering if we should change our default TypeScript runtime to maximize performances by default.
If we compare the number for dagger v0.19.6, we got:
│ bun.txt │ deno.txt │ node_yarn.txt │
...
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...
@burkhart-puzzle-ch you can use standard bash notation:
- Option 1:
USER=an\$example-user - Option 2:
USER='an$example-user'
stdout, err := e.client.Container().From(image).WithExec([]string{}).Stdout(ctx)
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
goimportssees undeclareddagand auto-importsdagger.io/dagger/dagwhich breaks everything - very annoying- Not always ...
👋 here's the repo with our nix flake. @sagikazarmark probably knows what's the right way to fix this given that he's a nix user :P
What happened? What did you expect to happen?
A new release of dagger is available: v0.19.7 → v0.19.8
To upgrade, see https://docs.dagger.io/install
https://github.com/dagger/dagger/releases/tag/v0.19.8
How can I disable update logging in the log output and prevent it from being output?
hi, I can't be disabled for the moment.
The Exodus
It's time! Let us boldly enter a YAML-free future!
Why?
- Faster and more repeatable end-to-end tests
- Simpler and cleaner configuration
- No drift between local and CI execution
- A Golden Example of solving real problems with Dagger
Target
Turn off GHA completely by December 31 2025.
Tasks
- Kill the monolith
- Migrate secrets to 1password
- [ ] Local release
- [ ] ...
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:
- how ma...
Problem
When configuring my module to use an SDK, if that SDK is itself a blueprint, loading it will fail with this error:
SDK does not support defining and executing functions
https://dagger.cloud/dagger/traces/fd56a6446143774a7cc9e42a3c0016d3
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 ...
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...
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...
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:
- 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...
Thanks for filing @toby-griffiths ! Original Discord thread for reference.
@toby-griffiths the error seems to indicate there is a .env file at ../../../.env. Does that file actually exist? And if so, is it a symlink by any chance? (ls -d ../../../.env)
By any chance is there a
.gitin your home directory?
Hi @toby-griffiths, quick ping on this. 🙏
So I've found a workaround, as I noticed this working in another project. If I create an empty .env file in the project directory it works.
Ah. Do if I also git init it seems to restrict it to the project root. Separate bug for this, because I would have expected to be able to create a module first, and then initialise the git repo, and it's worrying it's trying to tamper with the root of my home directory!
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
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...
EnvFile appears to be usable with Containers, that's why I'm after the equivalent for secrets
https://pkg.go.dev/dagger.io/dagger#Container.WithEnvFileVariables
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 ...
hey @AsocPro! are you using LiteLLM proxy or something else to connect Dagger with the AWS bedrock gateway?
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...
Does that mean it will not be possible to define a check on a root module, only use toolchains?
So if a specific check is needed, the solution would be for instance to create a sub module and reference it as a toolchain?
And maybe by extension to only toolchains in the main module, no custom code directly?
(yes, lot of questions, just to be sure to visualise the impact)
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....
The migration path for someone with a .dagger/ that has checks today would be:
- Move your
dagger.jsoninto.dagger/, delete thesourcefield dagger initat the top leveldagger toolchain install .dagger
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...
@vito this one's a good reference https://github.com/dagger/jest
It provides a toolchain for jest that bundles the otel library jest needs
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/daggercould have adaggermodule for programmatic use of Dagger as a product, and adagger-devtoolchain which is what we have now, purely focused on developing Dagger, not consuming it through an API.
[...]
Wouldn't the `.dag...
TLDR: maybe the root issue within the root issue, is discussing this 3d use case: programmatic use of as a product. Is that a thing we want & need? And if so, how do we explain it?
Let's take a project like Booklit: https://github.com/vito/booklit
Right now it's only Dagger code - but based on what's there now, it could probably be no Dagger code, which is gr...
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.
I see, thx! how would you expect this to work within a dagger module? Since you can map one 1password field to one dagger.Secret type at a time.
The way that I'd do this today with Dagger is by using the cmd://op item get $name --json which will pass that information into your module's argument. Is that something that might work for you?
@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?
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...
retrieve them how? Do those variables contain sensitive information?
example:
const container = client.container().from("alpine")
.withExec(["sh","-c","export FOO=bar"])
How to obtain the dynamic variable FOO
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.
I started migrating the engine integration test harness.
Notes so far:
Generated clients polish
As expected, generated clients have rough edges.
- Client generation is very slow on our repo: 2mn fully loaded, generating a go client on a warm cache. Example trace
- Lack of dynamic filtering was an issue: I had to manually add
engine/distconststo `dagg...
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...
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...
the linked PR enables wild-card function and argument matching, which I think solves this issue (a single customization stanza applying to all matching functions)
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...
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.
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...
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:
- `github.com/dagge...
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?
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.
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...
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...
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...
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...
What is the issue?
The Go linter golangci-lint errors out when linting the dagger module after having our Dagger module from v0.19.11 to v0.20.0.
Running dagger call go lint fails with:
Error: can't load config: the Go language version (go1.25) used to build golangci-lint is lower than the targeted Go version (1.26.0)
┃ The command is termi...
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?
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 ...
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
```...
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
┇...
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...
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...
Initial idea: function returns a *Span equivalent, and display that in the CLI/web UI
10x better CI: multiple returns of spans gives split screens - see your server logs and test logs at the same time
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=plainis still too verbose. It gets very crowded when there are multiple module dependencies. I'd almost want something that shows stdout of my immediatewithExecs 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...
[!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
defaultPathand `igno...
support for ${user.home}/.m2/settings.xml
https://github.com/dagger/dagger/issues/10542
For tracking.
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, ...
FYI @vito @jedevc
This is one aspect of #8235 that isn't yet tackled by Changeset. I think it's the last remaining issue though! Everything else is much better now :)
Context: I'm porting our CI to use Changeset
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.
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.Hostaccess 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...
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...
@jedevc you don't have to overload allow with token caps. Caps can be managed separately with their own flags. There is already a maxApiCalls argument to dag.llm() and there will be maxTokens as well. We can map separate arguments to that.
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...
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
ModuleBumpModeas I described above (which yea, is weird), we'd just need a booleanbump: 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...
but also see #10099 (comment)
I think those should be treated as separate issues. I mean, yeah, the module needs to know the version and it will...somehow, but that shouldn't affect the package management interface design IMO.
Oops. Coming back round to this, yup versioning constraints sounds good to me. We'd add a new field called constraint - on update, we'd refresh those constraints.
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...
This should not have been converted to an issue - tooling error, sorry (it can't be converted back :( )
Update: I rewrote this in the context of #11812
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...
Sorry this got converted to a discussion, but should have stayed an issue
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...
Sorry this got converted to a discussion, but could have stayed an issue. I re-created it -> https://github.com/dagger/dagger/issues/12828
Sorry this got converted to a discussion, but could have stayed an issue. I re-created it -> https://github.com/dagger/dagger/issues/12828
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
```...
FTR I implemented a configuration option in the dagger.json to be able to remaps ports. Configuration only, especially as it will better map with the new workspaces config file.
"portMappings": {
"grafana": ["3001:3000"]
}
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...
[dagger/dagger] Pull request opened: #12830 sdk(dang): fix Workspace args, parity with `/dagger-sdk`
Tried handing a native dang module to an LLM and found that quite a few things were missing or not actually supported:
Workspacearguments 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 fromgithub.com/vito/dang/dagger-sdk- Telemetry was wonky - the LLM would routinely miss logs that were emitted, because of...
Summary
- fix the custom registry mirror docs example so it executes
/hellobefore readingstdout - align the docs example with the built-in
dagger query --helpexample - 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 ...
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
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...
Sorry for the slow response, and sorry that this was moved to a discussion in the first place.
This is actionable and reproducible, so Ive opened #12833 to track it properly:
https://github.com/dagger/dagger/issues/12833
Theres also a fix up in #12831, which should be merged shortly:
https://github.com/dagger/dagger/pull/12831
Sorry for the slow response, and sorry that this was moved to a discussion in the first place.
This is actionable and reproducible, so I have re-opened an issue to track it properly.
There is also a fix up in #12831, which should be merged shortly:
https://github.com/dagger/dagger/pull/12831
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 oflog_outputconfiguration - Previously,
stop()was only called whenlog_outputwas 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...
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.
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=...)acceptsTextIObutsubprocess.Popen(stderr=...)requires a real file descriptor — passingStringIOcrashes withSessionError: Failed to start Dagger engine session: fileno- When
log_outputlacksfileno(), useos.pipe()+ a forwarding thread so anyTextIOworks 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...
Sorry about the slow response here, and for incorrectly moving this to a discussion.
I've opened #12836 to track this and PR #12837 with a fix — when log_output doesn't have a file descriptor, we now create a pipe and forward output in a background thread, so StringIO (and any other TextIO) works as documented.
Sorry about the slow response here, and for incorrectly moving this to a discussion.
I've opened #12836 to track this and PR #12837 with a fix — when log_output doesn't have a file descriptor, we now create a pipe and forward output in a background thread, so StringIO (and any other TextIO) works as documented.
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("...
Sorry about the slow response here, and for incorrectly moving this to a discussion.
I tested this on v0.20.3 and Directory.diff() works correctly now — the cache key computation error no longer reproduces. The fix landed somewhere between v0.18.2 and v0.20.3. If you're still hitting this, please let us know.
Tracking issue: #12838 (closed as fixed)
Sorry about the slow response here, and for incorrectly moving this to a discussion.
I tested this on v0.20.3 and Directory.diff() works correctly now — the cache key computation error no longer reproduces. The fix landed somewhere between v0.18.2 and v0.20.3. If you're still hitting this, please let us know.
Tracking issue: #12838 (closed as fixed)
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:...
Sorry about the slow response here, and for incorrectly moving this to a discussion.
This was fixed in v0.19.1 — the root cause was a bug in the midterm library's Screen.resizeX() where a resize could trigger an index-out-of-range panic. The fix landed in PR #11164 with a regression test. If you're still hitting this on v0.19.1+, please let us know.
Sorry about the slow response here, and for incorrectly moving this to a discussion.
This was fixed in v0.19.1 — the root cause was a bug in the midterm library's Screen.resizeX() where a resize could trigger an index-out-of-range panic. The fix landed in PR #11164 with a regression test. If you're still hitting this on v0.19.1+, please let us know.
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...
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...
Summary
dagger shellgives cryptic protobuf/base64 errors when passing a plain string where a custom object type is expected- Validates in
parseFlagValuethat 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 ...
Bug
dagger call exits with code 0 when a module function returning Void (Promise in TypeScript) fails. The TUI and Dagger Cloud trace show the error, but the CLI process exits successfully, causing CI to pass when it should fail.
Status
Fixed in PR #12000.
Originally reported in https://github.com/dagger/dagger/discussions/12816
Bug
dagger call exits with code 0 when a module function returning Void (Promise in TypeScript) fails. The TUI and Dagger Cloud trace show the error, but the CLI process exits successfully, causing CI to pass when it should fail.
Status
Fixed in PR #12000.
Originally reported in https://github.com/dagger/dagger/discussions/12816
Sorry about the slow response here, and for incorrectly moving this to a discussion.
This was fixed in PR #12000. Tracking issue: #12845 (closed as fixed). If you're still seeing exit code 0 on errors, please let us know.
Sorry about the slow response here, and for incorrectly moving this to a discussion.
This was fixed in PR #12000. Tracking issue: #12845 (closed as fixed). If you're still seeing exit code 0 on errors, please let us know.
Summary
WithExecwithExpand: truenow expands environment variables inRedirectStdout,RedirectStderr, andRedirectStdinpaths, not just command args.- Adds integration tests for redirect path expansion.
Fixes https://github.com/dagger/dagger/discussions/12818
Test plan
- [ ] New integration tests:
TestExecRedirectStdoutandTestExecRedirectStdinwith env var expansion - [ ] Existing expand tests continue to pass
Originally reported in https://github.com/dagger/dagger/discussions/12818
When Expand: true is set in WithExec, environment variables are expanded in command args but not in RedirectStdout, RedirectStderr, or RedirectStdin paths.
Fix: #12846
Sorry this got converted to a discussion, it got caught in a cleanup sweep. I re-created the issue: #12848. Fix is up in PR #12846.
Sorry this got converted to a discussion, it got caught in a cleanup sweep. I re-created the issue: #12848. Fix is up in PR #12846.
How about if we enforce root:root for all WithCacheVolume calls unless the Owner field is set in the call?
@sipsma @alexcb @tiborvass do you all agree with this? If so, I'll open an issue to track. (IMO not actionable as is unless we have consensus on what to do).
Summary
- When
SSH_AUTH_SOCKis 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...
Originally reported in https://github.com/dagger/dagger/discussions/12660
When SSH_AUTH_SOCK points to a stale or non-existent socket, module operations crash with a cryptic EOF error even when SSH features aren't being used.
Fix: #12849
Sorry this got converted to a discussion, it got caught in a cleanup sweep. I re-created the issue: #12850. Fix is up in PR #12849. @grouville wdyt?
Sorry this got converted to a discussion, it got caught in a cleanup sweep. I re-created the issue: #12850. Fix is up in PR #12849. @grouville wdyt?
Ahhh, yeah, this is a very fiddly known problem.
TL;DR: the typedefs in arguments/return values are "references". They're not fully populated.
If you modify your query to:
query directoryAsModule {
host {
directory(path: ".") {
name
asModule {
id
name
objects {
kind
asObject {
description
name
functions {
id
name
description
re...
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. ReadHostCustomCADirnow 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...
Originally reported in https://github.com/dagger/dagger/discussions/12739
When CA certs are mounted from a K8s Secret without subPath, files are symlinked through a ..data/ subdirectory. The cert installer preserves these symlinks, but inside containers the ..data/ directory doesn't exist, so the certs silently fail to load.
Fix: #12851
Sorry this got converted to a discussion and took so long to address. I re-created the issue: #12852. Fix is up in PR #12851.
Sorry this got converted to a discussion and took so long to address. I re-created the issue: #12852. Fix is up in PR #12851.
@andrestone hey, any chance you have been able to gather trace links or a repro since sipsma's last message? Would help us track down the remaining cases. Thanks!
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...
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:
CacheConfigForCallchecked theargsmap (which includes schema defaults fromExtractIDArgs) 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 `...
Sorry this got converted to a discussion, it got caught in a cleanup sweep. Apologies for the delay.
I reproduced the bug and re-created the issue: #12853. Fix is up in PR #12854.
Sorry this got converted to a discussion, it got caught in a cleanup sweep. Apologies for the delay.
I reproduced the bug and re-created the issue: #12853. Fix is up in PR #12854.
@burkhart-puzzle-ch you can use standard bash notation:
- Option 1:
USER=an\$example-user - Option 2:
USER='an$example-user'
Hello @shykes
Thanks for the feedback. Good to see there is a clear plan about it and things is going in a direction that makes sense to us.
I was not trying to blame the project here, just pointing out a thing that I would love to see for a project I like.
I agree about the tradeoff, but IMHO the Daggerverse as it is is more a hurdle for adoption. But i can be wrong.
When setting a JSON value in an EnvFile variable, quotes are stripped. For example:
ENV_JSON_GOOD={"foo": "bar"}
Results in {foo: bar} instead of {"foo": "bar"}.
Fix in progress: PR #12014.
Originally reported in #11889 (converted to discussion #12808 during triage).
Sorry this got converted to a discussion, it got caught in a cleanup sweep. I re-created the issue: #12855. Fix is in progress: PR #12014.
Sorry this got converted to a discussion, it got caught in a cleanup sweep. I re-created the issue: #12855. Fix is in progress: PR #12014.
[dagger/dagger] Issue opened: #12856 LLM tool specs have empty descriptions, breaking some providers
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 shellworks with modules that have undocumented functions when using AWS Bedrock
Fixes #12856
Sorry this got converted to a discussion, it got caught in a cleanup sweep. I re-created the issue: #12856. Fix is up in PR #12857.
Sorry this got converted to a discussion, it got caught in a cleanup sweep. I re-created the issue: #12856. Fix is up in PR #12857.
Toolchain customizations in dagger.json require the source code casing for function and argument names (e.g. ContainerEcho in Go), rather than the CLI-style names (e.g. container-echo). This is surprising since all other user-facing views use normalized names.
Fix in progress: PR #11906.
Originally reported in #11883 (converted to discussion #12806 during triage).
Sorry this got converted to a discussion, it got caught in a cleanup sweep. Apologies for the delay.
Since the conversion can't be reverted, I re-created the issue: #12858.
Sorry this got converted to a discussion, it got caught in a cleanup sweep. Apologies for the delay.
Since the conversion can't be reverted, I re-created the issue: #12858.
Summary
- The Helm chart hardcoded
execprobe commands in the DaemonSet and StatefulSet templates, then appendedreadinessProbeSettings/livenessProbeSettingsfrom values. This produced duplicate YAML keys when users customized probes, causing unmarshal errors. - Move the default
execcommand intovalues.yamldefaults and render the full probe from values in both templates. - Add
TestCustomProbescheck totoolchains/helm-devthat 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
...
Sorry this got converted to a discussion, it got caught in a cleanup sweep.
I re-created the issue: #12860. Fix is up in PR #12859.
Sorry this got converted to a discussion, it got caught in a cleanup sweep.
I re-created the issue: #12860. Fix is up in PR #12859.
Signed-off-by: Marcos Nils
Unfortunately I don't have deep Rust knowledge to collaborate properly but I will try to do so!
Resolves #10514 & completed work started by @wingyplus
See discussion #12594
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.FprintfvsWriteString(fmt.Sprintf)) consistent with existing QF exclusions - Fix gocritic
deprecatedCommentincore/modules/config.go(blank line beforeDeprecated:per godoc convention)
Each rule was revie...
Sorry this got converted to a discussion, it got caught in a cleanup sweep.
Your PR #11997 is the right fix. It was failing CI because golangci-lint v2.11 introduces new taint-analysis rules that flag existing code. PR #12863 excludes those rules after review. Once that merges, rebasing #11997 on top should pass CI.
Sorry this got converted to a discussion, it got caught in a cleanup sweep.
Your PR #11997 is the right fix. It was failing CI because golangci-lint v2.11 introduces new taint-analysis rules that flag existing code. PR #12863 excludes those rules after review. Once that merges, rebasing #11997 on top should pass CI.
Reported in #11977 (converted to discussion #12813).
The bundled golangci-lint in the Go toolchain is pinned to v2.5.0. Users upgrading to Dagger v0.20.0+ get an outdated linter.
External PR #11997 bumps to v2.11.3. PR #12863 excludes new lint rules that block it.
Reported in #11972 (converted to discussion #12811).
Dockerfile heredoc syntax (RUN <<EOF ... EOF) fails with exit 127 because /dev/pipes/ bind mounts get shadowed by runc's /dev tmpfs mount.
Fix: PR #12020.
Sorry this got converted to a discussion, it got caught in a cleanup sweep. I re-created the issue: #12865.
PR #12020 has the fix and CI is green.
Sorry this got converted to a discussion, it got caught in a cleanup sweep. I re-created the issue: #12865.
PR #12020 has the fix and CI is green.
Summary
- Add
progress.stop()callback toAsyncExitStackin_engine.pyso 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...
[dagger/dagger] Pull request opened: #12867 fix(sdk/python): handle in-memory streams for log_output
Summary
- Handle
TextIOstreams withoutfileno()(e.g.io.StringIO) inConfig.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_outputlacks `fi...
Summary
- Add regular-file checks in
innerEnvFile()andouterEnvFile()to skip directories named.env
Root Cause
dagger init crashes when .env exists as a directory because:
innerEnvFile()usesdirectory.exists(".env")which returns true for directoriesouterEnvFile()useshost.findUp(".env")which matches directories viaStat
Both then callhost.file()which fails on directories.
Fix
innerEnvFile(): AddexpectedType: REGULAR_TYPEto theexistsche...
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:
- Reproduce the CI failure locally (edits blocked)
- Isolate which stage/step fails
- Root cause analysis (confirm before fixing)
- Minimal fix to confirmed cause
- Verify the pipeline passes
The reproduce phase is critical for CI debugging — the agent must reprod...
Problem
When working with Claude Code, you have no visibility into context consumption, quota status, session cost, cache efficiency, or whether a tool has been stuck for 30 seconds.
Solution
claude-dash is a real-time statusline plugin that puts all of this in a two-line display below your prompt.

Quick Start
/plugin install clau...
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...
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...
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...
If you export the directory instead of a file to . doesn't that have the same effect?
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/...
Currently running Dagger on high enough verbosity in tmux or a nvim terminal causes a ton of output thrashing, because neither support synchronized rendering.
Now Tuist detects when sync is unavailable and falls back to using the alt screen.
Tuist also has a new Render API, so migrate everything over to that too.
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 docs group with 4 updates in the /docs directory: posthog-js, typedoc, typedoc-plugin-markdown and typescript.
Updates posthog-js from 1.360.2 to 1.364.1
Release notes
Sourced from posthog-js's releases.
posthog-js@1.364.1
1.364.1
Patch Changes
Updated dep...
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 ...
Bumps the sdk-typescript group with 16 updates in the /sdk/typescript directory:
| Package | From | To |
|---|---|---|
| @opentelemetry/api | 1.9.0 |
1.9.1 |
| @opentelemetry/core | 2.6.0 |
2.6.1 |
| @opentelemetry/exporter-jaeger | 2.6.0 |
2.6.1 |
| [@opentelemetry/exporter-trace-otlp-http](https://github.com/open... |
Bumps the engine group with 43 updates in the / directory:
| Package | From | To |
|---|---|---|
| charm.land/lipgloss/v2 | 2.0.1 |
2.0.2 |
| cloud.google.com/go/secretmanager | 1.14.7 |
1.16.0 |
| github.com/1password/onepassword-sdk-go | 0.3.1 |
0.4.0 |
| github.com/99designs/gqlgen | `0.17.... |
Review ready minus a few failing (non-related) tests https://github.com/dagger/dagger/pull/12872
clarify wording regarding automatic cert config por automatically provisioned engines
[dagger/dagger] Issue opened: #12883 🐞 URI secrets not transferred on cross-session dagql cache hits
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
- Module function creates a URI secret internally (not passed as argument) and returns a container using it (e.g.,
WithSecretVariable) - Sessio...
Collections
Table of Contents
Problem
Modules can discover dynamic sets of related objects, but there's no standard
way to publish them as keyed collections. Dagger has lists and objects but no
keyed sets. In practice, sets are almost always keyed — t...
Flag sdkTest, codegenTest, lint, and releaseDryRun with @check so they are automatically run in CI. The aggregator function (test) is intentionally left without @check.
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.
Base on PR https://github.com/dagger/dagger/pull/11779.
It needs to introduce the module attribute @generate to annotate the function.
once the module attribute annotated, the function should work with the dagger generate
[dagger/dagger] Pull request opened: #12890 fix(elixir-sdk-dev): fix generate function in elixir-sdk
- Change the function name
generatetoclientLibrary. - Fix
clientLibraryfunction to use introspection json fromdaggerEngineinstead of using from the input. - Remove
codegendependency. - Make
dagger generate elixir-sdkworks. - Generate the SDK to
sdk/elixir.
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...
is this somehing that was working ok and started happening out of nowhere? Or is this the first time you're running Dagger?
This had been working for months. Seen these timeouts occasionally, but now seeing them very frequently - maybe every other run, or more.
strange.. we're not seeing that ourselves. What registry are you pushing again? have you recenly updated Dagger?
Is ther eany other inputs you could give us which can help either repro or have more understanding why this started happening?
I will try to cut it down to a small reproducer tomorrow.
This is with dagger 0.20.3. Gitlab container registry.
Publishing of the container actually happens even in the event of the timeout, so I'm not sure yet that it is only when publishing.
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,...
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...
Bumps the engine group with 45 updates in the / directory:
| Package | From | To |
|---|---|---|
| charm.land/lipgloss/v2 | 2.0.1 |
2.0.2 |
| cloud.google.com/go/secretmanager | 1.14.7 |
1.16.0 |
| github.com/1password/onepassword-sdk-go | 0.3.1 |
0.4.0 |
| github.com/99designs/gqlgen | `0.17.... |
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.
I don't seem to be able to get any more log output from dagger via -vvv. Are there any other ways of getting more log output from the dagger internals? I have no access to any information at present about what it's doing when it is timing out.
@rgilton if you could somehow get the engine logs via docker logs $engine_container that'd be helpful. Are you running your pipelines in Gitlab's hosted CI runners or are the runners self-hosted?
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?
. Are you running your pipelines in Gitlab's hosted CI runners or are the runners self-hosted?
Self-hosted. Podman on Fedora.
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
Ok, it wasn't what I though. It'd be great if you could send us the dagger engine logs so we can continue troubleshooting.
Really don't need a TTY here - just poll against the log output.
This adds tags to the go toolchain, and configures the engine-dev to specify "dfexcludepatterns", "dfparents" tags, which are used to enable COPY --exlcude, and COPY --parents flags in the COPY and ADD dockerfile commands.
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/...
This PR is implementing the host volume mount for engines that are started locally, as well as allows sshfs mounts that would be used as two way binding mount from the engine to the container.
This feature allows large filesystems to be used in dagger workflows
Fixes https://github.com/dagger/dagger/issues/9326
Authored-by: @nikola-jokic
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... |
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.
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...
Refs #12902
Summary
- add
withVolatileVariable/withoutVolatileVariabletoContainer - make volatile vars visible only to future
withExeccalls - 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/schemaGOOS=linux GOARCH=arm64 go test -c -o /tmp/core-integration.test ./core/integration- ...
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...
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...
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:
configMapReforsecretRef
Fix
Indent name two additional spaces so it is cor...
- use standard semconv attributes for test name etc
- put useful error messages on failed test spans
- remove outdated, unused attributes
- rename weirdly named bench prewarm attribute
Mostly commeting here to highlight that all this is superceded by the new "Workspaces" API which has been recently merged here https://github.com/dagger/dagger/pull/11874
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 docs group with 6 updates in the /docs directory:
| Package | From | To |
|---|---|---|
| posthog-js | 1.360.2 |
1.364.7 |
| sass | 1.98.0 |
1.99.0 |
| typedoc | 0.28.17 |
0.28.18 |
| typedoc-plugin-markdown | 4.10.0 |
4.11.0 |
| [typescript](ht... |
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...
Bumps the sdk-typescript group with 18 updates in the /sdk/typescript directory:
| Package | From | To |
|---|---|---|
| @opentelemetry/api | 1.9.0 |
1.9.1 |
| @opentelemetry/core | 2.6.0 |
2.6.1 |
| @opentelemetry/exporter-jaeger | 2.6.0 |
2.6.1 |
| [@opentelemetry/exporter-trace-otlp-http](https://github.com/open... |
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...
No worries and thank you for your response :smile:! Our team is very happy with dagger, so it is nice to get to do some simple contributions at the very least.
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.
@marcosnils Is there any more info I can provide to help with working out what's going on here? We're still being hobbled by this issue. Unfortunately the only thing we can really do here is look to move to another way of building the container, as we don't really have resources available to start getting into the internals of the dagger engine :cry:
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...
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...
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...
@rgilton would it be possible to setup Dagger Cloud https://docs.dagger.io/reference/configuration/cloud/ and send us a trace when this occurs? In the meantime I'll try setting up a quick repro that publishes an image to the gitlab public registry and setup a cron workflow that runs every 15 minutes to try to repro
already set my test. You can find the job execution here: https://gitlab.com/marcosnils/dagger-ci-test/-/jobs?kind=BUILD
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).
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...
This is a revival of my previous attempt to have a Ruby SDK (see https://github.com/dagger/dagger/pull/9026)
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
Summary
- restore the lost
engine-dev-testingskill from workspace backup history - restore the
with-playground.shhelper used to boot a dev engine playground from source - keep the PR scoped to the playground skill only
Testing
bash -n skills/engine-dev-testing/with-playground.sh
Restored from backup workspace refs after the skill was lost during the workspace branch split/replay.
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...
Summary
- When a client connects from a subdirectory within a workspace, toolchain/blueprint source paths from
dagger.jsonwere resolved relative to the client's CWD instead of the config file location - Introduces
resolveConfigRefthat resolves relative tomoduleDirfor toolchains and blueprints, while keepingresolveLocalReffor the implicit module (whose path is already CWD-relative) - Adds a regression test that calls
detectAndLoadWorkspacewith a subdirectory CWD and verifi...
@rgilton as you can see my pipeline has ran several times for the past day and hasn't had a single timeout so far. Would it be possible to help us getting a me scoped reproducible example in gitlab so we can further assist?
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...
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...
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
generatefunction has been run, thecheckfunction must pass. And a subsequent call togeneratemust have no effect - if the
checkfunction doesn't pass, to run thegeneratefunction must fix it and ...
With 1. we say that the state on which we will run the
checkfunction is the one containing thegenerateresult. With 2. we are breaking the check-generate relation: thecheckcan pass, it doesn't mean ageneratecall 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
generatefunction can always return all files, and thencheckfurther 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.
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...
A bug was introduced recently (was not present in 0.20.3). When .env is found, its entire parent directory is uploaded by mistake. If that parent directory is your home directory - that gets uploaded entirely.
Summary
- Fixes #12938
- When loading the outer
.envfile, scope theHost.directory()call with anincludefilter so only the.envfile 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
.envexists - [ ] Confirm
.envloading still works as expected
🤖 Generated with Claude Code
Summary
- stop printing the legacy-default-path warning for compat-loaded modules
- keep the existing legacy default-path behavior unchanged
Testing
- GOOS=linux GOARCH=amd64 go test -c -o /tmp/core-compat-warning.test ./core
Summary
- Switch all in-repo modules from the external
github.com/vito/dang/dagger-sdk@8eba69d6...SDK source to the built-indangSDK shorthand. - Touches
dagger.jsonfor 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
dangSDK in CI.
Moving these tests from the Dang repo to Dagger, to cover the native SDK.
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/-Wplumbing 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 ./engineconninsdk/gogo test . -run ^TestWithWorkspace$insdk/godagger call engine-dev test --pkg=./core/integration --run=TestSession(CmdWorkspaceFlag|ClientParamsWorkspace)$(in ...
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...
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...
[dagger/dagger] Pull request opened: #12950 core(changeset): run git diff from an isolated empty cwd
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,...
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...
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
dagger init --sdk=go --source=. --name=minimal- Introduce a Go error, for example:
package main
type Minimal struct {
- 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...
Running dagger checks -l on my git repo gives a warning that 0.20.3 didn't:
WARN failed to open git repository err="branch config: invalid merge"
This reverts commits b53843246843aa9ee4c33b8fa1fd57533fdcc556 and 83529b0cb836c065ad8c663993b0985d69d647b7.
Without those reverts, sometimes lines are overlapping in the UI.
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/packagesreports 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-...
Restore toolchain ignoreGenerators support for dagger generate so generators excluded in dagger.json are omitted from dagger generate -l and skipped during generation again, including nested generator patterns. Fixes #12955.
Summary
- require
run()before reading generatorchangesorisEmpty - 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/...
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 ...
Summary
- The
Generatedcheck in.dagger/main.gowas relying onGeneratorGroup.IsEmpty(), which is broken. - Switch the function to take a
*dagger.Workspaceand use the workspace's generators directly, then read the patch contents fromChanges().AsPatch()instead of callingIsEmpty().
Test plan
- [ ] CI
check generatedjob runs successfully against this branch
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 generatedon 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...
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...
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-typescript group with 19 updates in the /sdk/typescript directory:
| Package | From | To |
|---|---|---|
| @opentelemetry/api | 1.9.0 |
1.9.1 |
| @opentelemetry/core | 2.6.0 |
2.6.1 |
| @opentelemetry/exporter-jaeger | 2.6.0 |
2.6.1 |
| [@opentelemetry/exporter-trace-otlp-http](https://github.com/open... |
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...
Bumps the docs group in /docs with 15 updates:
| Package | From | To |
|---|---|---|
| @docusaurus/core | 3.9.2 |
3.10.0 |
| @docusaurus/mdx-loader | 3.9.2 |
3.10.0 |
| @docusaurus/plugin-content-docs | 3.9.2 |
3.10.0 |
| [@docusau... |
Bumps the engine group with 15 updates in the / directory:
| Package | From | To |
|---|---|---|
| cloud.google.com/go/secretmanager | 1.16.0 |
1.18.0 |
| github.com/1password/onepassword-sdk-go | 0.3.1 |
0.4.0 |
| github.com/Microsoft/hcsshim | 0.14.0 |
0.14.1 |
| [github.com/anthropics/anthropic-sdk-go](https://github.com/anthropics/a... |
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")andworkspace.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 ...
Summary
A module using builtin sdk: "dang" does not behave consistently when calling dependency modules.
In a minimal repro on v0.20.5:
- builtin
dangparent -> builtindangchild: works - builtin
dangparent -> externaldangchild: works - builtin
dangparent -> Python child: works - builtin
dangparent -> Go child: fails - builtin
dangparent -> TypeScript child: fails
Both failures time out while loading the child module runtime.
This is the same failure shape I ...
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...
Summary
- Add a new reusable
markdown-lintmodule undermodules/markdownlint - Install it for our own repo's use
- Remove the broken markdownlint check from the project-specific
docs-devtoolchain - Fix existing markdown lint violations across the repo
Test plan
- [ ] Verify
dagger callon the markdown-lint module works - [ ] Confirm docs-dev toolchain still builds without the removed check
🤖 Generated with Claude Code
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 ...
@kpenfound - bumping incase lost in some noise. Thanks in advance
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...
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 ...
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:
- Find-up a git root (directory containing
.git). If found, that's the boundary. - 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 ...
Summary
- add
LoadWorkspaceModulesas the opt-in session/client flag and normalize the legacySkipWorkspaceModulesinput 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 -won touched Go filesGOCACHE=/tmp/dagger-go-build go test ./engine- `GO...
todo: codegen again
Summary
- Auto-promote the
-mremote git ref to the workspace inloadWorkspaceFromHostPathwhen CWD has no workspace markers (no.gitordagger.jsongoing up). Without this,dagger -m github.com/dagger/dagger@main check java-sdk:lintfrom a non-workspace directory resolves the toolchain'sdefaultPath="/"workspace arg against the empty CWD and can't find files that only exist in the remote repo. - Adds
ModuleSuite.TestRemoteWorkspaceToolchainDefaultPathwith two subtests — `e...
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:
- 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.
- Pushes the commit into a bare repo at /srv/repo.git in the same container.
- Serves /srv over smart-HTTP via gitSma...
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...
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 ...
The opt-in / opt-out PR changes the default workspace loading, and we forgot to remote those
Summary
- add
typescript-sdk:test-nodejs-ltsto the defaultci:bootstrapcheck 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...
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...
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:
FindsDaggerEnumswalks the type-grap...
Summary
Workspace.pathnow returns paths with a leading/(e.g./app/frontendinstead ofapp/frontend,/instead of.)- Aligns with the rest of the Workspace API which already uses leading-slash paths
Changes
engine/server/session_workspaces.go: usepath.Join("/", detected.Path)when settingcore.Workspace.Pathcore/workspace.go: update field doc to reflect the new format
Closes #12970
Test plan
- [x]
TestLocalWorkspaceAddresspasses (Docker, Go 1.25, ...
This reverts commit 4dba920e064c48dcfaf9e108949f5b4df8c11498.
This is causing issues with #11856 and we are priorizing the egraph changes.
I'll create a follow up PR with a new fixed based on egraph.
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...
What are you trying to do?
Using the helm chart to deploy dagger engine on a k8s cluster.
Why is this important to you?
Simpler consuming of the dagger Helm chart.
How are you currently working around this?
Applying from local directory by cloning the repo.
Improve our Go linter module:
dagger call go lint-module --module=...: previously the argument wasmod, and--modwas conflicting with the-m/--modofdaggerCLIdagger 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
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
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.
Fixes the display of service exposed by dagger up.
Previously:
✔ docs:up :8000
Now:
✔ docs:up http://localhost:8000
Also, enabling +up for the toolchains/docs-dev service, to serve the docs
Upgrade the Elixir image from 1.18.4 to 1.19.5-otp-28-alpine in both the runtime module and elixir-sdk-dev toolchain.
Fix module entrypoint crash by passing mix dagger.entrypoint.invoke as separate arguments to mix cmd instead of a single string — Elixir 1.19 changed how mix cmd parses its arguments.
Also bumps the engine version to v0.20.6 and updates Go dependencies.
What is the issue?
My dagger is currently regularly crashing with stack traces like
w/app/dagql/idtui/frontend_pretty.go:2144 +0xd8
created by github.com/dagger/dagger/dagql/idtui.(*frontendPretty).handleInputComplete in goroutine 82
/app/dagql/idtui/frontend_pretty.go:2141...
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: ...
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...
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...
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 ...
Bumps the docs group with 11 updates in the /docs directory:
| Package | From | To |
|---|---|---|
| @docusaurus/core | 3.9.2 |
3.10.0 |
| @docusaurus/plugin-content-docs | 3.9.2 |
3.10.0 |
| @docusaurus/preset-classic | 3.9.2 |
... |
Bumps the engine group with 23 updates in the / directory:
| Package | From | To |
|---|---|---|
| charm.land/lipgloss/v2 | 2.0.2 |
2.0.3 |
| cloud.google.com/go/secretmanager | 1.16.0 |
1.19.0 |
| github.com/1password/onepassword-sdk-go | 0.3.1 |
0.4.0 |
| github.com/Microsoft/hcsshim | `0.1... |
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...
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...
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...
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.
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 ...
You can't preserve the original filename on a File export today — the destination path is what dagger call export writes. Two options: export the containing Directory instead (.directory(...) then export --path . preserves filenames), or wrap the filename in the function output so the caller knows what to rename to. Directory-export is usually cleanest for build artifacts.
Yep, WithoutDirectory (and WithoutFile) paths are relative to the Directory receiver, not absolute. The confusion is that containerImage.Directory("/foo") returns a directory whose root is /foo, so /foo/bar is outside that root. The docs should definitely call this out — worth a small docs PR so nobody else hits the same thing. bar is the expected form.
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...
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...
Fix remote toolchains so +defaultPath resolves from the remote module selected by -m, not from the toolchain repo or local workspace.
Adds regression tests for both same-repo and cross-repo remote toolchains.
Alternative to #13020
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 ...
Use the shared shellcheck module (github.com/dagger/shellcheck) instead of the local copy. Delete the old one.
The old setup only linted install.sh. Now we lint all shell scripts in the repo, which turned up a bunch of warnings: unquoted variables, non-portable shebangs, cp -r vs cp -R, export PATH="$(…)" inlined, that kind of thing. This PR fixes all of them.
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.
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...
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....
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...
Summary
dagger mcp stopped exposing methods from the current workspace module in static mode.
This makes static MCP load workspace module query methods from the served schema.
It also adds integration tests for the four module and privileged mode combinations.
Summary
dagger mcp stopped exposing methods from the current workspace module in static mode.
This makes static MCP load workspace module query methods from the served schema.
It also adds integration tests for the four module and privileged mode combinations.
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...
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 ...
This is the rebased version of https://github.com/dagger/dagger/pull/11812, to avoid force-pushing on top of the PR and losing the history
First commit (d86aa527e01ea67cfa7afc827497eb78194f6fdf) is lockfile
Commit 487820c463d160c8e8ede5363b2543614d3858ac is the squashed history of the branch, without the last docs commit docs: fix 51 dead redirect targets and add 45 missing redirects
The in-between ...
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...
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...
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.
Bumps the sdk-typescript group in /sdk/typescript with 3 updates: @typescript-eslint/eslint-plugin, @typescript-eslint/parser and typescript-eslint.
Updates @typescript-eslint/eslint-plugin from 8.58.2 to 8.59.0
Release not...
Bumps the engine group with 25 updates in the / directory:
| Package | From | To |
|---|---|---|
| charm.land/lipgloss/v2 | 2.0.2 |
2.0.3 |
| cloud.google.com/go/secretmanager | 1.16.0 |
1.19.0 |
| github.com/1password/onepassword-sdk-go | 0.3.1 |
0.4.0 |
| github.com/99designs/gqlgen | `0.17.... |
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.
...
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...
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...
Fixes #13036.
Summary
- parse the platform printed by
dagger versionand the platform returned byContainer.platform()as OCI platforms - compare with
containerd/platforms.OnlyStrictsolinux/arm64matcheslinux/arm64/v8without accepting merely compatible platforms likelinux/arm/v8 - add focused regression coverage for the arm64/v8 installer output case
Verification
go test -run '^TestCheckDaggerVersionOutputPlatformVariant$' -count=1frome2e/installers- `git dif...
seems like this was accidentally added in a previous commit. Reverting to its originally intended state.
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...
One potential idea: if we get multiple calls which resolve to the same content digest (e.g. 4cdc3a12fdc416b7), maybe we can look it up under the cache always use the first one that was cached?
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://...
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
...
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...