No event handlers were registered. This script does nothing

Hello all,

I’ve been banging my head all day trying to figure this out and I’ve just about run out of patience. I would really appreciate some insight from some of you long time cloudflare workers users.

Im trying to deploy my first worker which uses Durable Objects. I read the docs and examined the sample chat application repo. I have a default export with a fetch method just as it says everywhere I read about it. This same file also exports a class called RealTimeServer.

This is my wrangler.toml

name = "socket"
type = "webpack"
zone_id = "****"
workers_dev = true
compatibility_date = "2021-10-27"
webpack_config = "./webpack.config.js"

[build.upload]
main="index.mjs"
format="modules"

[durable_objects]
bindings = [
  { name = "SOCKET", class_name = "RealTimeServer" } # Binding to our DurableObjectExample class
]

My webpack.config.js

module.exports = {
    mode: "production",
    target: "webworker",
    entry: "./index.mjs", // inferred from "main" in package.json
}

My package.json

{
  "name": "socket",
  "version": "1.0.0",
  "main": "./index.mjs",
  "license": "MIT"
}

As you can see it’s a barebones app as Im trying to learn how to use this new tech. I cannot get it to work with

wrangler dev

but I think this is expected as I read in the docs that wrangler doesn’t support Durable Objects yet. I was able to get it working on Miniflare with virtually no issues. Tested with postmna and it all works like a charm. Now I try

wrangler publish

and this is what I get

✨  Built successfully, built project size is 1 KiB.
Error: Something went wrong with the request to Cloudflare...
No event handlers were registered. This script does nothing.
 [API code: 10021]

Does anyone see something obviously wrong with the configs? Thanks for the help.

Looks like you’re missing your fetch handler

export default {
  fetch() {
    // code
  },
};

I wish it was that simple but as stated from what I can tell I have followed the docs and the examples correctly. This is my current default export.

export default {
    async fetch(request, env) {
      return await handleErrors(request, async () => {
        let id = env.SOCKET.idFromName(request.headers.get('x-session'));
        let socket = env.SOCKET.get(id);
        return await socket.fetch('', request);
      });
    }
}

I ran into the same problem and it turned out to be a webpack config issue. Basically just look at your post-build files in /dist and ensure that it’s using ES modules export syntax, i.e. something like:

export { thing as YourDurableObjectName, otherThing as default }

It appears if that’s not the case, Cloudflare will assume you’re not using the new modules syntax and start looking for an old event handler.

After some trial and error, I got this webpack config to work:

module.exports = {
  entry: './src/index.ts',
  output: {
    filename: 'index.mjs',
    path: path.join(__dirname, 'dist'),
    library: {
      type: 'module',
    },
  },
  experiments: {
    outputModule: true,
  },
  devtool: 'cheap-module-source-map',
  mode: 'development',
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],
  },
  module: {
    rules: [{
      test: /\.tsx?$/,
      loader: 'ts-loader',
    }, ],
  },
}

I was using typescript (sorry) but the critical bits I needed to change were type: 'module', and outputModule: true,.

It looks like someone put together a sample app that uses rollup instead of webpack, and here’s the config they used for that: durable-objects-typescript-rollup-esm/rollup.config.js at master · cloudflare/durable-objects-typescript-rollup-esm · GitHub

I hope this solves your problem like it did mine; if not, good luck :slight_smile: