Skip to main content

Interactive Debugging

Workflow failures can be both frustrating and lead to wasted resources as the team seeks to understand what went wrong and why. Dagger's interactive debugging feature is an invaluable tool in this situation.

Dagger lets users drop in to an interactive shell when a workflow run fails, with all the context at the point of failure. This is similar to a debugger experience, but without needing to set breakpoints explicitly. No changes are required to your code.

Here's an example of a workflow run failing, and Dagger opening an interactive terminal at the point of failure:

package main

import "context"

type MyModule struct{}

func (m *MyModule) Foo(ctx context.Context) (string, error) {
return dag.Container().
From("alpine:latest").
WithExec([]string{"sh", "-c", "echo hello world > /foo"}).
WithExec([]string{"cat", "/FOO"}). // deliberate error
Stdout(ctx)
}

// run with dagger call --interactive foo

See it in action:

You can also set one or more explicit breakpoints in your workflow, which then starts an interactive terminal session at each breakpoint. This lets you inspect a directory or a container at any point in your workflow run, with all the necessary context available to you.

Here's another example, which opens an interactive terminal at two different points in a workflow run to inspect the built container:

package main

import (
"context"
"dagger/my-module/internal/dagger"
)

type MyModule struct{}

func (m *MyModule) Foo(ctx context.Context) *dagger.Container {
return dag.Container().
From("alpine:latest").
Terminal().
WithExec([]string{"sh", "-c", "echo hello world > /foo"}).
Terminal()
}

See it in action:

Learn more