Skip to content

wrangler dev segfaults in local worker_loaders during repeated DynamicWorkerExecutor executions #6441

@chufucious

Description

@chufucious

wrangler dev segfaults in local worker_loaders during repeated DynamicWorkerExecutor executions

In local wrangler dev, repeated DynamicWorkerExecutor.execute() calls with moderate synthetic tool payloads crash the local workerd process with signal #11. The crash happens after several successful rounds, not on first execution. No JavaScript stack trace is produced.

The same code and payloads work without issue on deployed Cloudflare Workers.

Versions

Reproduced on:

wrangler @cloudflare/codemode OS
4.73.0 0.3.1 macOS Darwin 25.3.0, arm64
4.76.0 0.3.2 macOS Darwin 25.3.0, arm64
4.77.0 0.3.2 macOS Darwin 25.3.0, arm64

Minimal reproduction

wrangler.jsonc

{
  "name": "codemode-segfault-repro",
  "main": "src/index.ts",
  "compatibility_date": "2025-06-01",
  "compatibility_flags": ["nodejs_compat"],
  "worker_loaders": [{ "binding": "LOADER" }]
}

package.json

{
  "dependencies": {
    "@cloudflare/codemode": "^0.3.2",
    "wrangler": "^4.77.0"
  }
}

src/index.ts

import { DynamicWorkerExecutor, resolveProvider } from '@cloudflare/codemode';

interface Env {
  LOADER: ConstructorParameters<typeof DynamicWorkerExecutor>[0]['loader'];
}

export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);
    const count = Number(url.searchParams.get('count') ?? 80);
    const memoBytes = Number(url.searchParams.get('memoBytes') ?? 200);
    const rounds = Number(url.searchParams.get('rounds') ?? 6);

    const executor = new DynamicWorkerExecutor({
      loader: env.LOADER,
      timeout: 30_000,
    });

    const tools = {
      get_items: async () =>
        Array.from({ length: count }, (_, i) => ({
          id: `item_${i}`,
          name: `Item ${i}`,
          memo: 'x'.repeat(memoBytes),
        })),
    };

    for (let i = 0; i < rounds; i++) {
      const result = await executor.execute(
        `async () => { return await codemode.get_items(); }`,
        [resolveProvider({ name: 'codemode', tools })]
      );
      if (result.error) {
        return Response.json({ round: i, error: result.error }, { status: 500 });
      }
    }

    return Response.json({ ok: true, rounds, count, memoBytes });
  },
};

Observed behavior

wrangler dev

# Succeeds:
curl "http://localhost:8787?count=44&memoBytes=160&rounds=4"
# {"ok":true,"rounds":4,"count":44,"memoBytes":160}

# Crashes local workerd process:
curl "http://localhost:8787?count=112&memoBytes=220&rounds=6"
# curl: (52) Empty reply from server

Worker stderr:

*** Received signal #11: Segmentation fault: 11

Deployed behavior

Deployed to Cloudflare Workers, both parameter sets succeed. The smaller parameter set completes locally, while increasing both payload size and round count reproduces the crash consistently in this environment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions