How to create/deploy a Durable Object class without wrangler?

For reasons which have eluded me for years, I have never been able to get wrangler working on my local machine, so I just code in the dashboard - which works fine for my use cases so far.

However, I now want to use Durable Objects, and despite having read all the documentation several times over, I can not find how to create one without wrangler. So I went ahead and just put the class definition in the same script as my worker. It deploys fine, but there in not option to bind that Durable Object namespace to my worker in the dashboard, it says that I haven’t created any Durable Object classes.

What is the workaround here?

Wrangler is currently the only supported way to create durable object classes.

Assuming “eluded me for years” means you last tried wrangler 1, have you tried recent versions of wrangler? It’s an entirely different codebase, Install/Update Wrangler · Cloudflare Workers docs

Thanks for getting back to me, I appreciate it.

Ok, the issues with wrangler were absolutely in the latest version - and thankfully I finally solved it a few days after posting this message. Following the documentation to the letter did not work for me, despite several tries. Googling the errors I was getting did not work either, and even consulting with ChatGPT didn’t help, even though it tried hard, it eventually recommended I contact Cloudflare support :slight_smile:

The turn around point was when I did some deep digging and discovered that if I installed wrangler ‘locally’, but from my user home folder, it worked. Installing globally caused it somehow to install itself into a non-existent folder (???) - as in, it would install I could see the files there, but when I run it, wrangler would tell me that “wrangler is not installed”. I can’t really go into too much detail because by this time I was just trying things and suddenly it worked. But I know the crux was installing locally “only” from within my home directory. Installing locally from within my project directory never works, and neither did installing globally.

I’ll put my observations on Durable Objects in my next reply…

The next issue I faced was with the wrangler configuration documentation. Again, if I followed the documentation to the letter, it failed repeatedly. However, once I reformatted the toml file to use the double [[ format instead of how it is displayed in the documentation examples, it works.

So now for me all is working except for one remaining non-critical issue:

If I run a worker in wrangler which references a Durable Object, it works the first time - however if I leave wrangler running as wrangler dev and then call that worker again (via refreshing the localhost page for example) then I’ll get a string of Error 500s. It’s like it only retains the references to the Durable Objects for a few seconds and then forgets about them, and then when the worker runs again it doesn’t recreate the DOs, but simply crashes instead.

I restart wrangler, and all is good again for once worker call, but repeat calls create strings of Error 500s in the console.

I have the utmost respect for the quality of Cloudflare products and awesome team you obviously have, I would just recommend that you have someone re-check the documentation from the point of view of a completely naive user on a “blank” machine. You’ll find that there are many “gotcha” points where following the documentation to the letter leads to dead-ends and unaddressed errors which even determined Googling doesn’t find answers for. Ensuring your sample code snippets actually work for such a person (in the case of the wrangler configuration examples) would be incredibly helpful too - I think the documentation is overall good, but there a number of crucial spots where it makes implicit assumptions about the mindset of the reader and the development environment they are using, and once a user hits those blocks it is incredibly difficult to figure out what is going wrong. I was “this close” (like literally 2mins) to having to ditch Cloudflare Workers altogether for my project because I simply couldn’t see how my very simple worker deviated from the given samples in the documentation. If not for the strength of the rest of the Cloudflare stack, I definitely would have stopped sinking time into fixing these weird issues much sooner.

In summary, all is good now except for the mysterious crashing Durable Objects on repeated calls issue. Just have someone who is arms-length from the Workers development team take a critical look at the documentation please :slight_smile:

1 Like

When you say wrangler configuration documentation examples, are you talking about one of the Durable Object templates referenced from Using Durable Objects · Cloudflare Workers docs or something else?

I’ve raised the issue with 500s on wrangler dev to the appropriate people internally

I was especially referring to this page:

As the most excruciating example: this first sample at the top of page, when cut and pasted verbatim - did not work and it took many hours of investigating to find out why and how to fix it.

Top-level configuration

name = “my-worker”
main = “src/index.js”
compatibility_date = “2022-07-12”

workers_dev = false
route = { pattern = “*”, zone_name = “” }

kv_namespaces = [
{ binding = “<MY_NAMESPACE>”, id = “<KV_ID>” }

name = “my-worker-staging”
route = { pattern = “*”, zone_name = “” }

kv_namespaces = [
{ binding = “<MY_NAMESPACE>”, id = “<STAGING_KV_ID>” }

There were a few problems, but one I remember clearly was that wrangler complained about kv_namespaces being defined twice (did not recognize the two environments). And then when I simply removed one, wranger publish worked, but then saved “kv_namespaces” as a single env variable rather than recognizing that it was supposed to be mounting KV namespaces.

It did not work for me until I changed the format from this:

kv_namespaces = [
{ binding = “<MY_NAMESPACE>”, id = “<STAGING_KV_ID>” }

to this:

binding = “xxx”
id = “yyy”
preview_id = “zzz”

And yet, the only format that the durable objects would be understood and mounted was:

bindings = [
{ name = “abc”, class_name = “Abc” }


There were a few other weird things, but those were the two that I remember the most as far the configuration issues go. My they are my problem in whole or part, but if so it was inordinately difficult for me to discover the correct way to implement it.

As far the documentation for Durable Object themselves go, it is more easy to get right, just a couple of pieces of information are missing:

  • the fact that it it not possible to create them without wrangler
  • where to put the Durable Object definitions - in the same file as your worker? In the same directory but as separate files? This can be figured out, but it is not immediately obvious from reading the docs and when things don’t work it is tricky to understand how to proceed to find the problem.

I have personally got all this sorted (except the error 500s on repeated worker calls in wrangler dev), just sharing my experience in the hope that docs can be updated and make the experience easier for the next person.

Oh, I think one last thing which has me a little nervous when it comes to production deployment of this current project using Durable Objects. There seems little to no way for me to quickly and reliably introspect the state of Durable Objects in my product system. How many are there? How much data is being stored by them? If the worker is failing due to a Durable Object erroring out (perhaps because of a single field having too many bytes in it), how can I easily track that error down so I can correct with as little disturbance to the production code as possible. I feel like there are a few critical difference between the wrangler dev Durable Object experience and the production experience which makes me a little nervous about what to expect on production deployment and that there will be hidden glitches that will only come to light after the system is in real-world production use.

That makes me nervous :slight_smile: What would help a lot with this would be to ensure the the experience running a Durable Object including script via wrangler dev is identical to the deployed experience, and then offering some control panel tools for me to separately monitor what is happening to the data in my durable object instances, with the ability to manually do things like delete an object instance, or at least see a log of errors it might be experiencing. Something like at least what is already there for KV would be awesome!

Thanks for getting back to me on this, really appreciate the time taken!

That first sample cannot actually be cut and pasted verbatim, assuming you don’t own the domain. Removing the workers_dev and route lines, putting in valid KV ids and binding names, then publishing works for me. I would encourage you to submit a bug report at GitHub - cloudflare/workers-sdk: ⛅️ Home to Wrangler, the CLI for Cloudflare Workers® with the toml you were using and the errors you saw.

  • the fact that it it not possible to create them without wrangler
  • where to put the Durable Object definitions

The documentation at Using Durable Objects · Cloudflare Workers docs says " The easiest way to upload Workers that implement or bind to Durable Objects is to use Wrangler" I can put in a PR to change “easiest” to say “supported”, but either way hopefully it’s clear that wrangler is what’s intended to be used to manage durable objects.

The templates linked from that same section have examples of how to organize definitions into files. Either the same file as your worker like durable-objects-template/src at master · cloudflare/durable-objects-template · GitHub or separate files like durable-objects-rollup-esm/src at master · cloudflare/durable-objects-rollup-esm · GitHub will work.

If you were not aware of that section of the docs, any suggestion on how to make it more discoverable would be welcome.

error 500s on repeated worker calls in wrangler dev

That is being investigated, but in the meantime I’d encourage you to use local mode (type ‘l’ after running wrangler dev) or use the latest version of wrangler which uses local mode by default

How many are there

There is a graphql api described in Using Durable Objects · Cloudflare Workers docs As things stand today, if you want further introspection, you’ll need to send a message to one of the durable objects obtained from the listing api Durable Objects · Cloudflare Workers docs, or send a message from the durable object to another system. If you don’t have an existing system that you can send analytics to, you may want to check out Workers Analytics Engine (beta) · Cloudflare Analytics docs

do things like delete an object instance

Given that durable objects are implicitly created on first access if they don’t already exist, I’m curious what your expected outcome would be of an attempt to fetch from a DO concurrently with or after an attempt to delete that DO. If that’s not a concern for you and you’re just asking how to get rid of the data in a given DO that you know for sure you’re never sending another request to, call .deleteAll() on it Durable Objects · Cloudflare Workers docs