{"record":{"id":"efeede6cb9244988","repo":"firecrawl/open-lovable","slug":"unsupported-sandbox-type","errorCode":null,"errorMessage":"Unsupported sandbox type","messagePattern":"Unsupported sandbox type","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/api/apply-ai-code/route.ts","lineNumber":454,"sourceCode":"          // Replace shadow-3xl with shadow-2xl (shadow-3xl doesn't exist)\n          fileContent = fileContent.replace(/shadow-3xl/g, 'shadow-2xl');\n          // Replace any other non-existent shadow utilities\n          fileContent = fileContent.replace(/shadow-4xl/g, 'shadow-2xl');\n          fileContent = fileContent.replace(/shadow-5xl/g, 'shadow-2xl');\n        }\n        \n        console.log(`[apply-ai-code] Writing file using E2B files API: ${fullPath}`);\n        \n        try {\n          // Check if we're using provider pattern (v2) or direct sandbox (v1)\n          if (sandbox.writeFile) {\n            // V2: Provider pattern (Vercel/E2B provider)\n            await sandbox.writeFile(file.path, fileContent);\n          } else if (sandbox.files?.write) {\n            // V1: Direct E2B sandbox\n            await sandbox.files.write(fullPath, fileContent);\n          } else {\n            throw new Error('Unsupported sandbox type');\n          }\n          console.log(`[apply-ai-code] Successfully wrote file: ${fullPath}`);\n          \n          // Update file cache\n          if (global.sandboxState?.fileCache) {\n            global.sandboxState.fileCache.files[normalizedPath] = {\n              content: fileContent,\n              lastModified: Date.now()\n            };\n            console.log(`[apply-ai-code] Updated file cache for: ${normalizedPath}`);\n          }\n          \n        } catch (writeError) {\n          console.error(`[apply-ai-code] E2B file write error:`, writeError);\n          throw writeError as Error;\n        }\n        \n        ","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/firecrawl/open-lovable/blob/69bd93bae7a9c97ef989eb70aabe6797fb3dac89/app/api/apply-ai-code/route.ts#L436-L472","documentation":"Thrown by the apply-ai-code route when the connected sandbox object exposes neither the V2 provider interface (`writeFile` on the sandbox) nor the V1 E2B direct interface (`sandbox.files.write`). It signals that the sandbox SDK instance in `global.activeSandbox` does not match any file-writing API shape the route knows how to use, so files from generated AI code cannot be persisted.","triggerScenarios":"POST /api/apply-ai-code with an activeSandbox that was created by a different SDK version (e.g. a plain object, a Daytona or other provider sandbox without `writeFile`, or an E2B beta SDK where `files` is undefined), or activeSandbox being set to a stale/partially-initialized object.","commonSituations":"Upgrading or downgrading the `e2b` / `e2b-Code-interpreter` packages so the API surface changed; mixing providers (Vercel sandbox vs E2B) so neither branch matches; a hot-reload wiping the real sandbox but leaving a stale global reference.","solutions":["Log `Object.keys(global.activeSandbox)` (and of `files`) at the start of the route to confirm which API shape the sandbox actually has","Pin/align the sandbox SDK version so the app's V1 or V2 code path matches the installed package","Add the missing branch for the provider in use (e.g. call the provider's own write helper) before the throw","Ensure the sandbox is created through the same factory the rest of the app uses, then re-create it and retry"],"exampleFix":"// before\n} else if (sandbox.files?.write) {\n  await sandbox.files.write(fullPath, fileContent);\n} else {\n  throw new Error('Unsupported sandbox type');\n}\n// after\n} else if (sandbox.files?.write) {\n  await sandbox.files.write(fullPath, fileContent);\n} else if (typeof sandbox.writeFile === 'function') {\n  await sandbox.writeFile(file.path, fileContent);\n} else if (typeof sandbox.fs?.writeFile === 'function') {\n  await sandbox.fs.writeFile(fullPath, fileContent);\n} else {\n  throw new Error(`Unsupported sandbox type: ${sandbox?.constructor?.name}`);\n}","handlingStrategy":"validation","validationCode":"function canWriteFiles(sandbox) {\n  return Boolean(sandbox) && (typeof sandbox.writeFile === 'function' || Boolean(sandbox.files?.write));\n}\nif (!canWriteFiles(global.activeSandbox)) throw new Error('Sandbox does not support file writes; recreate it');","typeGuard":"function isWritableSandbox(s: any): s is { writeFile?: (p: string, c: string) => Promise<unknown>; files?: { write: (p: string, c: string) => Promise<unknown> } } {\n  return typeof s?.writeFile === 'function' || typeof s?.files?.write === 'function';\n}","tryCatchPattern":"try {\n  await applyAiCode(files);\n} catch (e) {\n  if (e.message === 'Unsupported sandbox type') {\n    await recreateSandbox();\n    return applyAiCode(files); // retry once with a fresh sandbox\n  }\n  throw e;\n}","preventionTips":["Create sandboxes only via the app's single factory so the API shape is guaranteed","Log Object.keys(sandbox) once at creation to detect SDK shape drift after upgrades","Pin sandbox SDK versions in package.json and test apply-ai-code after any bump","Add a startup smoke test that writes a temp file through the chosen API path"],"tags":["sandbox","api-surface-mismatch","e2b"],"backgroundTag":"unsupported-sandbox-type","analyzedSha":"69bd93bae7a9c97ef989eb70aabe6797fb3dac89","analyzedAt":"2026-08-28T22:20:32.339Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}