firecrawl/open-lovable · error · Error
No active sandbox
Error message
No active sandbox
What it means
E2BProvider throws 'No active sandbox' when a lifecycle method (runCommand) is called before a sandbox instance exists. this.sandbox is only assigned by createSandbox() (or reconnect()); every operation guards on it and fails fast. It signals a programming-order mistake, not a sandbox runtime failure.
Source
Thrown at lib/sandbox/providers/e2b-provider.ts:75
createdAt: new Date()
};
// Set extended timeout on the sandbox instance if method available
if (typeof this.sandbox.setTimeout === 'function') {
this.sandbox.setTimeout(appConfig.e2b.timeoutMs);
}
return this.sandboxInfo;
} catch (error) {
console.error('[E2BProvider] Error creating sandbox:', error);
throw error;
}
}
async runCommand(command: string): Promise<CommandResult> {
if (!this.sandbox) {
throw new Error('No active sandbox');
}
const result = await this.sandbox.runCode(`
import subprocess
import os
os.chdir('/home/user/app')
result = subprocess.run(${JSON.stringify(command.split(' '))},
capture_output=True,
text=True,
shell=False)
print("STDOUT:")
print(result.stdout)
if result.stderr:
print("\\nSTDERR:")
print(result.stderr)View on GitHub (pinned to 69bd93bae7)
Solutions
- Call `await provider.createSandbox()` before any runCommand/writeFile/readFile/listFiles/installPackages/setupViteApp/restartViteServer call
- Check `if (!provider.hasActiveSandbox?.()) await provider.createSandbox()` at the start of each request
- If the sandbox expired, reconnect via `await provider.reconnect(sandboxId)` or recreate it
- Wrap provider usage in a lazy-init helper that creates the sandbox once and reuses it
Example fix
// before
const provider = new E2BProvider();
await provider.runCommand('ls');
// after
const provider = new E2BProvider();
await provider.createSandbox();
await provider.runCommand('ls'); Defensive patterns
Strategy: validation
Validate before calling
if (!provider.sandbox) {
await provider.createSandbox();
}
await provider.runCommand(command); Type guard
function hasActiveSandbox(p): p is E2BProvider & { sandbox: NonNullable<E2BProvider['sandbox']> } {
return p.sandbox != null;
} Try / catch
try {
await provider.runCommand(cmd);
} catch (e) {
if (e instanceof Error && e.message === 'No active sandbox') {
await provider.createSandbox();
return provider.runCommand(cmd);
}
throw e;
} Prevention
- Always await createSandbox() immediately after constructing the provider
- Wrap provider operations in an ensureSandbox() helper
- Track E2B sandbox TTL and refresh before expiry
- Never swallow createSandbox() errors — a failed create leaves null state
- Use one provider instance per sandbox lifetime
When it happens
Trigger: Calling provider.runCommand(cmd) without first awaiting provider.createSandbox(); using a freshly constructed E2BProvider; calling after a sandbox expired/crashed and this.sandbox was reset without recreation.
Common situations: Instantiating the provider in a route handler and calling runCommand immediately; sandbox idled out mid-session (E2B timeouts) so the reference is stale/null; race where two requests share one provider and one closed it; forgetting createSandbox() after a refactor.
Related errors
- Unsupported sandbox type
- No active sandbox
- Failed to create zip: ${error}
- Failed to read zip file: ${error}
- Failed to list files
AI-assisted analysis of firecrawl/open-lovable@69bd93bae7 (2026-08-28).
Data as JSON: /api/errors/577ed8a27c315a7a.
Report an issue: GitHub.