dagger/dagger · error
failed to evaluate container: %w
Error message
failed to evaluate container: %w
What it means
The container's full evaluation (build steps) failed before the terminal could be opened. Dagger intentionally evaluates the container completely first so that progress output isn't interrupted by the terminal UI, then wraps any evaluation error.
Source
Thrown at core/terminal.go:190
if err != nil {
return fmt.Errorf("failed to get client metadata: %w", err)
}
if clientMetadata.SessionID == "" {
return fmt.Errorf("terminal attach container: empty session ID")
}
attachedAny, err := cache.AttachResult(ctx, clientMetadata.SessionID, srv, containerRes)
if err != nil {
return fmt.Errorf("failed to attach terminal container: %w", err)
}
attached, ok := attachedAny.(dagql.ObjectResult[*Container])
if !ok {
return fmt.Errorf("failed to attach terminal container: expected %T, got %T", containerRes, attachedAny)
}
containerRes = attached
// HACK: ensure that container is entirely built before interrupting nice
// progress output with the terminal
if err := cache.Evaluate(ctx, containerRes); err != nil {
return fmt.Errorf("failed to evaluate container: %w", err)
}
query, err := CurrentQuery(ctx)
if err != nil {
return err
}
container, err = cloneContainerForTerminal(ctx, query, containerRes.Self())
if err != nil {
return fmt.Errorf("failed to clone terminal container: %w", err)
}
term, output, err := prepTerminal(ctx, selectedID, execErr)
if err != nil {
return err
}
defer term.Close(bkgwpb.UnknownExitStatus) // always close term; it's wrapped in a once so it won't be called multiple times
container.Config.Env = prepTerminalEnv(output, container.Config.Env)
containerRes, err = newSyntheticTerminalContainerResult(srv, container, "terminal_container")View on GitHub (pinned to 82ba2681db)
Solutions
- Read the wrapped inner error — it names the failing build step
- Run the same chain without .Terminal() to see the underlying build error directly
- Fix the failing step (correct image ref, add registry auth, fix RUN command)
- Use dagger call with --progress to see full build output
Example fix
// before
ctr := client.Container().From("alpine:nope").Terminal()
// after
ctr := client.Container().From("alpine:latest").Terminal() Defensive patterns
Strategy: validation
Validate before calling
// pre-evaluate without terminal to surface build errors cleanly
if _, err := ctr.Sync(ctx); err != nil {
return fmt.Errorf("container not buildable, fix before terminal: %w", err)
}
_, err := ctr.Terminal(ctx) Try / catch
if err != nil {
var execErr *dagger.ExecError
if errors.As(err, &execErr) { /* inspect execErr.ExitCode */ }
return err
} Prevention
- Run dagger call with --progress to catch failing steps early
- Pin base image tags you control
- Verify registry auth (DOCKER_CONFIG / ~/.docker/config.json) before terminal
- Test the build chain without .Terminal() first
When it happens
Trigger: Calling Container.Terminal() on a container whose lazily-evaluated DAG (FROM, RUN, etc.) fails during evaluation, e.g. a failing RUN step or unresolvable image.
Common situations: Bad base image tag or private registry auth; failing RUN command; network failure during build; a multi-stage build step error surfacing only when terminal forces evaluation.
Related errors
- failed to evaluate terminal base container: %w
- evaluate changeset diff directory: %w
- failed to evaluate changeset diff snapshot: %w
- diff snapshot: %w
- diff path: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/1dcfda2e20fe2b65.
Report an issue: GitHub.