dagger/dagger · error · ErrNoCurrentWorkspace

%w: workspace arguments are not inherited by module runtime

Error message

%w: workspace arguments are not inherited by module runtime calls; pass a Workspace explicitly

What it means

Workspaces are auto-injected only for calls originating outside a module function (direct CLI/SDK or schema-walking flows like `dagger generate`). If the call is running inside a module function body and no workspace is bound in context, loadWorkspaceArg refuses to inherit the caller's workspace and returns ErrNoCurrentWorkspace with this message, preventing silent cross-module workspace inheritance.

Source

Thrown at core/modfunc.go:1274

	// is still explicit here — the group threaded it via WorkspaceToContext —
	// so this does not silently inherit a caller's workspace across modules.
	if boundWS, ok := WorkspaceFromContext(ctx); ok {
		wsID, err := boundWS.ID()
		if err != nil {
			return nil, fmt.Errorf("get bound workspace ID: %w", err)
		}
		return dagql.NewID[*Workspace](wsID), nil
	}

	// Otherwise a Workspace is auto-injected only for calls originating outside a
	// module function (a direct CLI/SDK client, or a schema-walking flow like
	// `dagger generate`). A running module function must pass a Workspace to its
	// dependencies explicitly, so a dependency does not silently inherit its
	// caller's workspace.
	if inModuleFunction, err := callerInModuleFunction(ctx); err != nil {
		return nil, err
	} else if inModuleFunction {
		return nil, fmt.Errorf("%w: workspace arguments are not inherited by module runtime calls; pass a Workspace explicitly", ErrNoCurrentWorkspace)
	}

	var ws dagql.ObjectResult[*Workspace]
	err := dag.Select(ctx, dag.Root(), &ws,
		dagql.Selector{
			Field: "currentWorkspace",
			Args: []dagql.NamedInput{
				{Name: "skipMigrationCheck", Value: dagql.Boolean(true)},
			},
		},
	)
	if err != nil {
		return nil, fmt.Errorf("load workspace: %w", err)
	}

	wsID, err := ws.ID()
	if err != nil {
		return nil, fmt.Errorf("get workspace ID: %w", err)

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Pass a Workspace explicitly to the dependency function from your module code
  2. If the caller has no workspace, create one (e.g. from a Directory) before calling the dependency
  3. If the dependency should not require a workspace, change its signature to take a Workspace explicitly or drop the auto-inject

Example fix

// before
dep.Provider(ctx) // dependency declares Workspace! auto-inject
// after
ws := dag.Workspace(dag.Host().Directory("."))
dep.Provider(ctx, dagql.WorkspaceInput{Workspace: ws})
Defensive patterns

Strategy: validation

Validate before calling

// in module code, before calling a dependency that declares Workspace!
if ws == nil {
	ws = dag.Workspace(dag.Host().Directory("."))
}
_ = ws // pass ws explicitly to the dependency call

Try / catch

_, err := fn.Call(ctx, ...)
if errors.Is(err, ErrNoCurrentWorkspace) {
	// pass an explicit Workspace to the dependency
}

Prevention

When it happens

Trigger: A module function calls another module function whose dependency declares a Workspace! (auto-inject) parameter, without passing a Workspace explicitly, from inside the module runtime.

Common situations: Chaining module functions where a dependency function signature gained a Workspace parameter; upgrading Dagger after this guard was introduced and previously-inheriting code now errors.

Related errors


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