the universal sandbox runtime for agents and humans. pocketenv.io
sandbox openclaw agent claude-code vercel-sandbox deno-sandbox cloudflare-sandbox atproto sprites daytona
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

Normalize and propagate sandbox IDs

Add a normalizeId option to SandboxOptions and the Cloudflare provider.
When enabled, compute a lowercased normalizedId, pass it into the
CloudflareSandbox (id() now returns the normalized value), and persist
the normalized sandboxId to the DB when starting a sandbox. Also use
record.sandboxId as a fallback across API routes when interacting with
provider instances.

+31 -11
+16 -7
apps/cf-sandbox/src/index.ts
··· 174 174 id: record!.id, 175 175 keepAlive: params.keepAlive, 176 176 sleepAfter: params.sleepAfter, 177 + normalizeId: true, 177 178 }); 178 179 const sandboxId = await sandbox.id(); 179 180 ··· 249 250 250 251 try { 251 252 sandbox = await createSandbox("cloudflare", { 252 - id: c.req.param("sandboxId"), 253 + id: record.sandboxId ?? c.req.param("sandboxId"), 253 254 memory: "4GiB", 254 255 }); 255 256 ··· 353 354 } 354 355 355 356 await sandbox.start(); 357 + const normalizedId = await sandbox.id(); 356 358 await c.var.db 357 359 .update(sandboxes) 358 - .set({ status: "RUNNING", startedAt: new Date() }) 360 + .set({ 361 + status: "RUNNING", 362 + startedAt: new Date(), 363 + sandboxId: normalizedId ?? record.sandboxId, 364 + }) 359 365 .where(eq(sandboxes.id, c.req.param("sandboxId"))) 360 366 .execute(); 361 367 } catch (err) { ··· 384 390 let sandbox: BaseSandbox | null = null; 385 391 386 392 sandbox = await createSandbox("cloudflare", { 387 - id: c.req.param("sandboxId"), 393 + id: record.sandboxId ?? c.req.param("sandboxId"), 388 394 }); 389 395 390 396 if (!sandbox) { ··· 430 436 let sandbox: BaseSandbox | null = null; 431 437 432 438 sandbox = await createSandbox("cloudflare", { 433 - id: c.req.param("sandboxId"), 439 + id: record.sandboxId ?? c.req.param("sandboxId"), 434 440 }); 435 441 436 442 const { command } = await c.req.json(); ··· 461 467 let sandbox: BaseSandbox | null = null; 462 468 463 469 sandbox = await createSandbox("cloudflare", { 464 - id: c.req.param("sandboxId"), 470 + id: record.sandboxId ?? c.req.param("sandboxId"), 465 471 }); 466 472 467 473 await sandbox.delete(); ··· 505 511 } 506 512 } 507 513 508 - const sandbox = getSandbox(c.env.Sandbox, c.req.param("sandboxId")); 514 + const sandbox = getSandbox( 515 + c.env.Sandbox, 516 + record.sandboxId ?? c.req.param("sandboxId"), 517 + ); 509 518 const sessionId = c.req.query("session"); 510 519 511 520 const cfsandbox = await createSandbox("cloudflare", { 512 - id: c.req.param("sandboxId"), 521 + id: record.sandboxId ?? c.req.param("sandboxId"), 513 522 }); 514 523 515 524 const params = await Promise.all([
+14 -4
apps/cf-sandbox/src/providers/cloudflare/index.ts
··· 4 4 import path from "node:path"; 5 5 6 6 export class CloudflareSandbox implements BaseSandbox { 7 - constructor(private sandbox: Sandbox) {} 7 + private normalizedId: string | null; 8 + 9 + constructor( 10 + private sandbox: Sandbox, 11 + normalizedId?: string, 12 + ) { 13 + this.normalizedId = normalizedId ?? null; 14 + } 8 15 9 16 private async retryWithBackoff<T>( 10 17 fn: () => Promise<T>, ··· 51 58 } 52 59 53 60 async id(): Promise<string | null> { 54 - return null; 61 + return this.normalizedId; 55 62 } 56 63 57 64 async setEnvs(envVars: Record<string, string>): Promise<void> { ··· 120 127 throw new Error("Sandbox ID is required for Cloudflare provider"); 121 128 } 122 129 130 + const normalize = options.normalizeId ?? false; 131 + const normalizedId = normalize ? options.id.toLowerCase() : options.id; 132 + 123 133 const sandbox = getSandbox(env.Sandbox, options.id, { 124 134 keepAlive: options.keepAlive, 125 135 sleepAfter: options.sleepAfter, 126 - normalizeId: true, 136 + normalizeId: normalize, 127 137 }); 128 - return new CloudflareSandbox(sandbox); 138 + return new CloudflareSandbox(sandbox, normalizedId); 129 139 } 130 140 } 131 141
+1
apps/cf-sandbox/src/providers/index.ts
··· 30 30 ports?: number[]; 31 31 snapshotRoot?: string; 32 32 port?: number; 33 + normalizeId?: boolean; 33 34 [key: string]: any; 34 35 } 35 36