mastra-ai/mastra · error

A session workspace must be a valid Workspace instance.

Error message

A session workspace must be a valid Workspace instance.

What it means

The AgentController accepts a workspace for session-scoped file/tool access, but it must be an actual Workspace instance (not a plain object, path string, or config). The constructor throws when a truthy workspace value is passed that fails the instanceof check, so misconfigured workspaces fail loudly at construction rather than at first tool call.

Source

Thrown at packages/core/src/agent-controller/session.ts:2905

    this.thread = new SessionThread(() => this.identity.getResourceId());
    this.displayState = new SessionDisplayState({
      getTokenUsage: () => this.getTokenUsage(),
      getSubagentDisplayName: agentType => this.#resolveSubagentName?.(agentType),
      getThreadId: () => this.thread.getId(),
      clearFollowUps: () => this.followUps.clear(),
    });
    this.#bus.setDisplayState(this.displayState);
    this.state = new SessionState(state ?? { initialState: {} as TState }, this.#bus, () => {
      // Pin persistence to the thread active when the state update was
      // requested — a queued preference update must not land in the metadata
      // of a thread the session switched to in the meantime.
      const threadId = this.thread.getId();
      if (threadId === null) return undefined;
      return args => this.thread.setSettingOn({ threadId, ...args });
    });

    if (workspace !== undefined && !(workspace instanceof Workspace)) {
      throw new Error(`A session workspace must be a valid Workspace instance.`);
    }

    this.#workspace = workspace;
    this.browser = browser;
  }

  /**
   * This session's scoping tags (e.g. `{ projectPath }`), stamped onto every
   * thread it creates. Returns a copy; empty when the session is unscoped.
   */
  getTags(): Record<string, string> {
    return { ...this.#tags };
  }

  /**
   * The scope this session's threads carry: what `thread.create()` stamps and
   * what thread selection filters on. Both must read it here — computing it on
   * each side is what let selection drift off the controller-global state while

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Construct a real Workspace instance (new Workspace(...)) from the same package version the core uses.
  2. If accepting a path from config, wrap it: new Workspace(path).
  3. Verify the import source of Workspace matches the one AgentController instanceof-checks (no duplicate package installs).

Example fix

// before
new AgentControllerSession({ workspace: '/my/project' }); // throws
// after
import { Workspace } from '@mastra/core/workspace';
new AgentControllerSession({ workspace: new Workspace('/my/project') });
Defensive patterns

Strategy: validation

Validate before calling

if (workspace !== undefined && !(workspace instanceof Workspace)) {
  throw new Error('workspace must be a Workspace instance; wrap paths with new Workspace(path)');
}

Type guard

function isWorkspace(w: unknown): w is Workspace {
  return w instanceof Workspace;
}

Try / catch

try {
  const session = new AgentControllerSession({ workspace });
} catch (e) {
  if (e instanceof Error && e.message.includes('valid Workspace instance')) {
    const session = new AgentControllerSession({ workspace: new Workspace(workspace as string) });
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a raw object shaped like a Workspace, a filesystem path string, a config/options bag, or a Workspace from a different/incompatible package version to the session/controller constructor.

Common situations: Version mismatch where Workspace moved packages; passing workspace root path string instead of new Workspace(...); JSON-deserialized workspace config lacking the class prototype.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/887e93cee7518d6a. Report an issue: GitHub.