dagger/dagger · error

cannot export a synthetic workspace

Error message

cannot export a synthetic workspace

What it means

The workspace's base source is *WorkspaceSourceDirectory — a synthetic, in-engine directory with no git or host backing. There is no host path to expose for a purely synthetic workspace, so ExportHostPath refuses.

Source

Thrown at core/workspace.go:446

	}
}

func (ws *Workspace) ExportHostPath() (string, error) {
	if ws == nil {
		return "", fmt.Errorf("workspace is required")
	}
	switch src := ws.BaseSource().(type) {
	case *WorkspaceSourceClientLocal:
		if src.HostPath == "" {
			return "", fmt.Errorf("workspace export requires a local Git workspace")
		}
		return src.HostPath, nil
	case *WorkspaceSourceRootlessLocal:
		return "", fmt.Errorf("workspace export requires a local Git workspace")
	case *WorkspaceSourceGitRef:
		return "", fmt.Errorf("cannot export a remote Git workspace")
	case *WorkspaceSourceDirectory:
		return "", fmt.Errorf("cannot export a synthetic workspace")
	case nil:
		return "", fmt.Errorf("workspace export requires a local Git workspace")
	default:
		return "", fmt.Errorf("cannot export workspace source %T", src)
	}
}

func (ws *Workspace) IsValueWorkspace() bool {
	if ws == nil || ws.ClientID != "" {
		return false
	}
	switch ws.Source().(type) {
	case *WorkspaceSourceDirectory, *WorkspaceSourceGitRef, *WorkspaceSourceOverlay:
		return true
	default:
		return false
	}
}

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Export the directory contents via Directory.Export to a host destination instead of using ExportHostPath
  2. Construct the workspace from a client-local git directory if a host path is genuinely required
  3. Guard the call by checking the workspace source type first

Example fix

// before
path, err := ws.ExportHostPath()
// after
dir := ws.Directory()
if err := dir.Export(ctx, "./out"); err != nil {
  return err
}
path := "./out"
Defensive patterns

Strategy: fallback

Validate before calling

if _, ok := ws.BaseSource().(*core.WorkspaceSourceDirectory); ok {
  return ws.Directory().Export(ctx, dest) // synthetic: export contents, not a path
}

Type guard

func isSynthetic(ws *core.Workspace) bool {
  _, ok := ws.BaseSource().(*core.WorkspaceSourceDirectory)
  return ok
}

Try / catch

path, err := ws.ExportHostPath()
if err != nil && strings.Contains(err.Error(), "synthetic workspace") {
  return ws.Directory().Export(ctx, dest)
}

Prevention

When it happens

Trigger: Calling ExportHostPath on a workspace built from a Directory (e.g. container.directory(...) or a constructed directory tree) rather than a client-local git checkout.

Common situations: Composing workspaces from generated directories in a pipeline, then trying to pass a host path to a local tool or test harness; forgetting that only client-local git workspaces have host paths.

Related errors


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