mastra-ai/mastra · error
${this.constructor.name} implements neither start() nor the
Error message
${this.constructor.name} implements neither start() nor the create() acquisition primitive, so starting it would do nothing. Implement one using method syntax. What it means
The default start() on MastraSandbox throws when a subclass implements neither start() nor the create() acquisition primitive. Starting such a sandbox would be a no-op, so the library fails immediately with guidance to use method syntax (class-field definitions are invisible to the constructor's validation).
Source
Thrown at packages/core/src/workspace/sandbox/mastra-sandbox.ts:545
* decomposes into lookup/wake/provision.
* 2. Override `start()` returning {@link SandboxStartResult} — for
* providers with a fused getOrCreate-style API where decomposition
* would add round-trips.
* 3. Override `start()` returning void — the outcome is unknown.
*
* The base constructor wraps `start()` so direct calls are routed through
* `_start()`. Use METHOD syntax when overriding — a class-field `start`
* initializer would overwrite the wrapper. Implementing neither rung throws:
* a sandbox with nothing to start says so with an empty `async start() {}`.
*
* Id-keyed getOrCreate contract: a sandbox constructed with a known `id`
* resolves that id on start — reconnect/resume when the provider finds an
* existing VM for it, create otherwise.
*/
async start(): Promise<SandboxStartResult | void> {
// Also where a misspelled override and a class-FIELD `start`/`create` land,
// since field initializers run too late for the constructor to see them.
throw new Error(
`${this.constructor.name} implements neither start() nor the create() acquisition primitive, so starting it would do nothing. Implement one using method syntax.`,
);
}
/**
* Ensure the sandbox is running.
*
* Calls `_start()` if status is not 'running'. Useful for lazy initialization
* where operations should automatically start the sandbox if needed.
*
* This is the lazy entry point into the id-keyed getOrCreate contract
* described on {@link start}.
*
* @throws {SandboxNotReadyError} if the sandbox fails to reach 'running' status
*
* @example
* ```typescript
* async executeCommand(command: string): Promise<CommandResult> {View on GitHub (pinned to 75dd419e61)
Solutions
- Implement `async create()` (and optionally `find()`/`connect()`) using method syntax on your subclass.
- Or override `async start()` itself with method syntax if your provider has custom acquisition logic.
- Move any class-field arrow function definitions of start/create/connect/find to regular methods.
Example fix
// before
class MySandbox extends MastraSandbox {
create = async () => { this.handle = await provider.launch(); };
}
// after
class MySandbox extends MastraSandbox {
async create() { this.handle = await provider.launch(); }
} Defensive patterns
Strategy: validation
Validate before calling
const proto = MySandbox.prototype as any;
if (typeof proto.start !== 'function' ||
(proto.start === MastraSandbox.prototype.start && typeof proto.create !== 'function')) {
throw new Error('MySandbox must implement start() or create() using method syntax');
} Type guard
function isStartable(sb: object): boolean {
const p = sb.constructor?.prototype ?? sb;
return typeof (p as any).create === 'function' || typeof (p as any).start === 'function';
} Try / catch
try {
await sandbox.start();
} catch (e) {
if (e instanceof Error && /implements neither start\(\) nor/.test(e.message)) {
throw new Error(`Misconfigured sandbox subclass ${sandbox.constructor.name}`, { cause: e });
}
throw e;
} Prevention
- Implement create() (or start()) with regular method syntax in every sandbox subclass.
- Never define start/create as class-field arrow functions — the constructor cannot see them.
- Grep your subclass for misspelled lifecycle method names before shipping.
- Smoke-test each sandbox subclass's start() in CI.
When it happens
Trigger: Calling start() on a sandbox subclass that only defines helper methods, or that declared start/create as class-field arrow functions, or misspelled the override (e.g. `onStart`/`creat` instead of `create`).
Common situations: Writing a minimal custom sandbox provider and forgetting the acquisition primitive; converting methods to arrow-function fields during a refactor; copying a subclass and deleting create() while leaving call sites.
Related errors
- Sandbox '${sandbox.id}' cannot run the session setup: no exe
- ${this.constructor.name}: find() requires connect() to adopt
- connect({ id, name }): "name" is required when connecting wi
- MemoryThread.${methodName}() requires an agentId. Pass it vi
- execa is not available in Cloudflare Workers
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/65872536bd8c10e8.
Report an issue: GitHub.