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

  1. Read the wrapped inner error — it names the failing build step
  2. Run the same chain without .Terminal() to see the underlying build error directly
  3. Fix the failing step (correct image ref, add registry auth, fix RUN command)
  4. 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

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


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/1dcfda2e20fe2b65. Report an issue: GitHub.