Skip to content

[BUG] Build Fails Due to Missing Durable Object Classes in Worker Configuration #502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
eposha opened this issue Mar 26, 2025 · 27 comments
Closed
Labels
bug Something isn't working triage

Comments

@eposha
Copy link

eposha commented Mar 26, 2025

Describe the bug

When attempting to create an optimized production build, the process fails due to missing Durable Object classes in the worker configuration. The following warnings and errors are encountered:

workerd/server/server.c++:1951: warning: A DurableObjectNamespace in the config referenced the class "DurableObjectQueueHandler", but no such Durable Object class is exported from the worker. Please make sure the class name matches, it is exported, and the class extends 'DurableObject'. Attempts to call to this Durable Object class will fail at runtime, but historically this was not a startup-time error. Future versions of workerd may make this a startup-time error.

workerd/server/server.c++:1951: warning: A DurableObjectNamespace in the config referenced the class "DOShardedTagCache", but no such Durable Object class is exported from the worker. Please make sure the class name matches, it is exported, and the class extends 'DurableObject'. Attempts to call to this Durable Object class will fail at runtime, but historically this was not a startup-time error. Future versions of workerd may make this a startup-time error.

service core:user:__WRANGLER_EXTERNAL_DURABLE_OBJECTS_WORKER: Worker "core:user:__WRANGLER_EXTERNAL_DURABLE_OBJECTS_WORKER"'s binding "DurableObjectQueueHandler" refers to a service "core:user:worker", but no such service is defined.

unhandledRejection [MiniflareCoreError [ERR_RUNTIME_FAILURE]: The Workers runtime failed to start. There is likely additional logging output above.] {
  code: 'ERR_RUNTIME_FAILURE',
  cause: undefined
}

Error: Command failed: npm run build

Steps to reproduce

wrangler.json

{
  "$schema": "node_modules/wrangler/config-schema.json",
  "main": ".open-next/worker.js",
  "name": "my app",
  "compatibility_date": "2024-12-30",
  "compatibility_flags": ["nodejs_compat"],
  "minify": true,
  "assets": {
    "directory": ".open-next/assets",
    "binding": "ASSETS",
  },
  "placement": {
    "mode": "smart",
  },
  "observability": {
    "enabled": true,
  },
  "r2_buckets": [
    {
      "bucket_name": "dimlly-isr-tags",
      "binding": "dimlly_isr_tags",
    },
  ],

  "durable_objects": {
    "bindings": [
      {
        "name": "NEXT_CACHE_REVALIDATION_DURABLE_OBJECT",
        "class_name": "DurableObjectQueueHandler",
      },
      {
        "name": "NEXT_CACHE_DO_SHARDED",
        "class_name": "DOShardedTagCache",
      },
    ],
  },
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": ["DurableObjectQueueHandler", "DOShardedTagCache"],
    },
  ],
}

open-next.config.ts

import { defineCloudflareConfig } from '@opennextjs/cloudflare';
import kvIncrementalCache from '@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache';
import memoryQueue from '@opennextjs/cloudflare/overrides/queue/do-queue';
import doShardedTagCache from '@opennextjs/cloudflare/overrides/tag-cache/do-sharded-tag-cache';

export default defineCloudflareConfig({
  incrementalCache: kvIncrementalCache,
  tagCache: doShardedTagCache({ baseShardSize: 12, regionalCache: true }),
  queue: memoryQueue,
});

Expected behavior

Fix

@opennextjs/cloudflare version

0.6.0

Wrangler version

4.5.0

next info output

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.3.0;
Binaries:
  Node: 23.5.0
  npm: 10.9.2
  Yarn: N/A
  pnpm: 9.15.4
Relevant Packages:
  next: 15.2.4
  eslint-config-next: 15.2.4
  react: 19.0.0
  react-dom: 19.0.0
  typescript: 5.8.2
Next.js Config:
  output: N/A

Additional context

No response

@eposha eposha added bug Something isn't working triage labels Mar 26, 2025
@conico974
Copy link
Collaborator

Please provide a reproduction. There is nothing we can do from this

@eposha
Copy link
Author

eposha commented Mar 26, 2025

@conico974
Copy link
Collaborator

Looks like initOpenNextCloudflareForDev is broken.
I think it tries to find these durable objects at build time (during next build)
@vicb @dario-piotrowicz any idea ?

@eposha
Copy link
Author

eposha commented Mar 26, 2025

@conico974

One more thing
In the help r2 cache configuration documentation, in open-next.config.ts you need to add this configuration to

open-next.config.ts

import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
import { withRegionalCache } from "@opennextjs/cloudflare/overrides/incremental-cache/regional-cache";
import doQueue from "@opennextjs/cloudflare/overrides/queue/do-queue";
// ...
 
// With regional cache enabled:
export default defineCloudflareConfig({
  incrementalCache: withRegionalCache(r2IncrementalCache, {
    mode: "long-lived",
    shouldLazilyUpdateOnCacheHit: true,
  }),
  queue: doQueue,
  // ...
});

But then in On-Demand Revalidation when you select doShardedTagCache you need to change it to this configuration

import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache";
import memoryQueue from "@opennextjs/cloudflare/overrides/queue/do-queue";
import doShardedTagCache from "@opennextjs/cloudflare/overrides/tag-cache/do-sharded-tag-cache";
 
export default defineCloudflareConfig({
  incrementalCache: kvIncrementalCache,
  tagCache: doShardedTagCache({ baseShardSize: 12, regionalCache: true }),
  queue: memoryQueue,
});

So incrementalCache changes

Is that right?

However, I have tried both options, it does not solve the current problem

@conico974
Copy link
Collaborator

Remove initOpenNextCloudflareForDev from next-config.
You can choose the incrementalCache you want, if you want to keep R2, just keep it.

@eposha
Copy link
Author

eposha commented Mar 26, 2025

Yes, removing initOpenNextCloudflareForDev from next.config solved the issue

But when using this configuration

import { defineCloudflareConfig } from '@opennextjs/cloudflare';
import r2IncrementalCache from '@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache';
import { withRegionalCache } from '@opennextjs/cloudflare/overrides/incremental-cache/regional-cache';
import memoryQueue from '@opennextjs/cloudflare/overrides/queue/do-queue';
import doShardedTagCache from '@opennextjs/cloudflare/overrides/tag-cache/do-sharded-tag-cache';

export default defineCloudflareConfig({
  incrementalCache: withRegionalCache(r2IncrementalCache, {
    mode: 'long-lived',
    shouldLazilyUpdateOnCacheHit: true,
  }),
  tagCache: doShardedTagCache({ baseShardSize: 12, regionalCache: true }),
  queue: memoryQueue,
});

I get this error

Populating R2 incremental cache...
✘ [ERROR] Unknown argument: /cache-bug/.open-next/cache/tA8oDUrywn8eVm41L2eD2/index.cache


🪵  Logs were written to "/Library/Preferences/.wrangler/logs/wrangler-2025-03-26_19-45-10_192.log"
ERROR Wrangler command failed

wrangler log

--- 2025-03-26T19:45:10.316Z debug
🪵  Writing logs to "/Users/andrej/Library/Preferences/.wrangler/logs/wrangler-2025-03-26_19-45-10_192.log"
---

--- 2025-03-26T19:45:10.316Z debug
Metrics dispatcher: Posting data {"deviceId":"842124de-eebd-453c-8ee4-ea50275c8542","event":"wrangler command started","timestamp":1743018310315,"properties":{"amplitude_session_id":1743018310311,"amplitude_event_id":0,"wranglerVersion":"4.5.0","osPlatform":"Mac OS","osVersion":"Darwin Kernel Version 24.3.0: Thu Jan  2 20:24:16 PST 2025; root:xnu-11215.81.4~3/RELEASE_ARM64_T6000","nodeVersion":22,"packageManager":"npm","isFirstUsage":false,"configFileType":"jsonc","isCI":false,"isPagesCI":false,"isWorkersCI":false,"isInteractive":false,"hasAssets":true,"argsUsed":["j"],"argsCombination":"j","command":"wrangler r2 object put /Users/andrej/Desktop/space/cache-bug/.open-next/cache/tA8oDUrywn8eVm41L2eD2/index.cache","args":{"xJsonConfig":true,"j":true,"objectPath":"<REDACTED>"}}}
---

--- 2025-03-26T19:45:10.325Z log

---

--- 2025-03-26T19:45:10.410Z error
�[31m✘ �[41;31m[�[41;97mERROR�[41;31m]�[0m �[1mUnknown argument: /cache-bug/.open-next/cache/tA8oDUrywn8eVm41L2eD2/index.cache�[0m


---

--- 2025-03-26T19:45:10.482Z debug
Metrics dispatcher: Posting data {"deviceId":"842124de-eebd-453c-8ee4-ea50275c8542","event":"wrangler command errored","timestamp":1743018310481,"properties":{"amplitude_session_id":1743018310311,"amplitude_event_id":1,"wranglerVersion":"4.5.0","osPlatform":"Mac OS","osVersion":"Darwin Kernel Version 24.3.0: Thu Jan  2 20:24:16 PST 2025; root:xnu-11215.81.4~3/RELEASE_ARM64_T6000","nodeVersion":22,"packageManager":"npm","isFirstUsage":false,"configFileType":"jsonc","isCI":false,"isPagesCI":false,"isWorkersCI":false,"isInteractive":false,"hasAssets":true,"argsUsed":["j"],"argsCombination":"j","command":"wrangler r2 object put /Users/andrej/Desktop/space/cache-bug/.open-next/cache/tA8oDUrywn8eVm41L2eD2/index.cache","args":{"xJsonConfig":true,"j":true,"objectPath":"<REDACTED>"},"durationMs":203,"durationSeconds":0.203,"durationMinutes":0.0033833333333333337,"errorType":"CommandLineArgsError","errorMessage":"yargs validation error"}}
---

reproduction is here

https://github.com/eposha/opennext-cloudflare-r2-cache-issue

@conico974
Copy link
Collaborator

@james-elicx any idea ?

@vicb
Copy link
Contributor

vicb commented Mar 26, 2025

I created cloudflare/workers-sdk#8687 for the initOpenNextCloudflareForDev issue.

@james-elicx
Copy link
Collaborator

reproduction is here

eposha/opennext-cloudflare-r2-cache-issue

Thanks. The R2 issue was a problem with npm and yarn due to how CLI flags are passed around. It should have been fixed by #505, which was released in 0.6.2.

@muhamad-rizki
Copy link

muhamad-rizki commented Mar 27, 2025

hi @james-elicx PR #505 is make my build broken with error:
✘ [ERROR] Error: must provide --command or --file.
it seems the -- make --command not working, the final args looks below

[
  'd1 execute',
  'NEXT_TAG_CACHE_D1',
  '--',
  '--command="CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE);"',
  '--remote'
]

I use yarn and npm on Windows and Cloudflare CI both of them throwing same error. I use npm 10.9.2, yarn 4.5.0, node v22

@james-elicx
Copy link
Collaborator

hi @james-elicx PR #505 is make my build broken with error: ✘ [ERROR] Error: must provide --command or --file. it seems the -- make --command not working, the final args looks below

[
  'd1 execute',
  'NEXT_TAG_CACHE_D1',
  '--',
  '--command="CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE);"',
  '--remote'
]

I use yarn and npm on Windows and Cloudflare CI both of them throwing same error. I use npm 10.9.2, yarn 4.5.0, node v22

HI @muhamad-rizki, please can you share a reproduction? I'm unable to reproduce this locally.

@muhamad-rizki
Copy link

muhamad-rizki commented Mar 27, 2025

hi @james-elicx PR #505 is make my build broken with error: ✘ [ERROR] Error: must provide --command or --file. it seems the -- make --command not working, the final args looks below

[
  'd1 execute',
  'NEXT_TAG_CACHE_D1',
  '--',
  '--command="CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE);"',
  '--remote'
]

I use yarn and npm on Windows and Cloudflare CI both of them throwing same error. I use npm 10.9.2, yarn 4.5.0, node v22

HI @muhamad-rizki, please can you share a reproduction? I'm unable to reproduce this locally.

sure here you go https://github.com/muhamad-rizki/cfnextjs-repro
it happens only on deploy command due to executing D1 populateCache

Creating D1 table if necessary...
✘ [ERROR] Error: must provide --command or --file.

@james-elicx
Copy link
Collaborator

sure here you go muhamad-rizki/cfnextjs-repro it happens only on deploy command due to executing D1 populateCache

Creating D1 table if necessary...
✘ [ERROR] Error: must provide --command or --file.

Thanks, yeah, this looks like a difference between how yarn classic and yarn modern work. I was testing with yarn classic earlier, but I can reproduce with yarn modern.

Have raised #512 to fix.

@vicb
Copy link
Contributor

vicb commented Mar 28, 2025

The DO part of the issue will be fixed with cloudflare/workers-sdk#8697 that should land in wrangler next week.

Meanwhile you can add a script_name to your working binding and set that to your worker name as a workaround.

@zoroblox
Copy link

zoroblox commented Mar 31, 2025

Hello, I got into the same issue. Has this been fixed?

I tried to add the "script_name" workaround as mentioned by @vicb but then i got into a new error when deploying: "Cannot apply new-class migration to class 'DurableObjectQueueHandler' that is not exported by script."

@conico974
Copy link
Collaborator

@zoroblox What did you put as script_name ? Try with .open-next/worker.js

@zoroblox
Copy link

Hi @conico974, thank you for your reply. I initially put the "script_name": "My worker name" in the wrangler.jsonc - I tried to replaced it as "script_name": ".open-next/worker.js" as you suggested. But i got into the same error when i tried to deploy using "npm run deploy" as below. Can you please help me on how to fix it:

Your worker has access to the following bindings:

  • Durable Objects:
    • NEXT_CACHE_DO_QUEUE: DurableObjectQueueHandler (defined in .open-next/worker.js)
  • KV Namespaces:
    • NEXT_INC_CACHE_KV: ...
  • Services:
    • WORKER_SELF_REFERENCE: ...
  • Assets:
    • Binding: ASSETS

✘ [ERROR] A request to the Cloudflare API (/accounts/.../workers/scripts/...) failed.

Cannot apply new-class migration to class 'DurableObjectQueueHandler' that is not exported by
script. [code: 10070]

If you think this is a bug, please open an issue at:
https://github.com/cloudflare/workers-sdk/issues/new/choose

@conico974
Copy link
Collaborator

@zoroblox Could you share your wrangler.jsonc file ? I've tested with the script_name set to the worker binding and it works just fine

@zoroblox
Copy link

zoroblox commented Mar 31, 2025

@conico974 Here is my wrangler.jsonc file. I'm trying to create a next js app with prisma connecting to supabase. If i removed the durable objects bindings, the deployment works but i can't use next js caching. Can you please look into it

{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "app_name",
  "main": ".open-next/worker.js",
  "compatibility_date": "2024-12-30",
  "compatibility_flags": ["nodejs_compat"],
  "assets": {
    "binding": "ASSETS",
    "directory": ".open-next/assets"
  },
  "observability": {
    "enabled": true
  },
  "kv_namespaces": [
    {
      "binding": "NEXT_INC_CACHE_KV",
      "id": "id..."
    }
  ],
  "services": [
    {
      "binding": "WORKER_SELF_REFERENCE",
      "service": "app_name"
    }
  ],
  "durable_objects": {
    "bindings": [
      {
        "name": "NEXT_CACHE_DO_QUEUE",
        "class_name": "DurableObjectQueueHandler",
        "script_name": ".open-next/worker.js"
      }
    ]
  },
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": ["DurableObjectQueueHandler"]
    }
  ]
}

@zoroblox
Copy link

@conico974 Here is my wrangler.jsonc file. I'm trying to create a next js app with prisma connecting to supabase. If i remove the durable objects bindings, the deployment works but i can't use next js caching. Can you please look into it

{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "app_name",
  "main": ".open-next/worker.js",
  "compatibility_date": "2024-12-30",
  "compatibility_flags": ["nodejs_compat"],
  "assets": {
    "binding": "ASSETS",
    "directory": ".open-next/assets"
  },
  "observability": {
    "enabled": true
  },
  "kv_namespaces": [
    {
      "binding": "NEXT_INC_CACHE_KV",
      "id": "id..."
    }
  ],
  "services": [
    {
      "binding": "WORKER_SELF_REFERENCE",
      "service": "app_name"
    }
  ],
  "durable_objects": {
    "bindings": [
      {
        "name": "NEXT_CACHE_DO_QUEUE",
        "class_name": "DurableObjectQueueHandler",
        "script_name": ".open-next/worker.js"
      }
    ]
  },
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": ["DurableObjectQueueHandler"]
    }
  ]
}

@conico974
Copy link
Collaborator

@zoroblox You tried setting it to "app_name" right ? And what versions of @opennextjs/cloudflare are you using ?

@zoroblox
Copy link

@zoroblox You tried setting it to "app_name" right ? And what versions of @opennextjs/cloudflare are you using ?

@conico974 My bad, i'm so sorry. I updated @opennextjs/cloudflare and wrangler to the latest version and now the error is gone. Thank you so much

@ibobo
Copy link

ibobo commented Apr 2, 2025

I'm still having the same issue, also with script_name set.

This is my wrangler.toml:

name = "..."
main = ".open-next/worker.js"
compatibility_date = "2025-04-01"
compatibility_flags = [ "nodejs_compat" ]
upload_source_maps = true
placement = { mode = "smart" }

[[routes]]
  pattern = "..."
  custom_domain = true

[assets]
directory = ".open-next/assets"
binding = "ASSETS"

[vars]
VAR = "..."

[observability]
enabled = true
head_sampling_rate = 1

[[kv_namespaces]]
binding = "NEXT_CACHE_WORKERS_KV"
id = "..."

[[services]]
binding = "WORKER_SELF_REFERENCE"
service = "..."

[[durable_objects.bindings]]
name = "NEXT_CACHE_DO_QUEUE"
class_name = "DurableObjectQueueHandler"
script_name = ".open-next/worker.js"

[[migrations]]
tag = "v1"
new_sqlite_classes = ["DurableObjectQueueHandler"]

[[d1_databases]]
binding = "NEXT_TAG_CACHE_D1"
database_name = "OpennextTagCache"
database_id = "..."

This is what I get in the build:

Worker saved in `/opt/buildhome/repo/web/.open-next/worker.js` 🚀

OpenNext build complete.

┌──────────────────────────────┐
│ OpenNext — Cloudflare deploy │
└──────────────────────────────┘

Monorepo detected at /opt/buildhome/repo
Incremental cache does not need populating

Creating D1 table if necessary...

Successfully created D1 table

Cloudflare collects anonymous telemetry about your usage of Wrangler. Learn more at https://github.com/cloudflare/workers-sdk/tree/main/packages/wrangler/telemetry.md

 ⛅️ wrangler 4.6.0
------------------

🌀 Building list of assets...
🌀 Starting asset upload...
🌀 Found 13 new or modified static assets to upload. Proceeding with upload...
+ /BUILD_ID
...
+ /cdn-cgi/_next_cache/V6z2kQB5obJmuWO7F_cFF/_not-found.cache
+ /_next/static/chunks/435-6b0c9b6d589ecf02.js
Uploaded 4 of 13 assets
Uploaded 8 of 13 assets
Uploaded 13 of 13 assets
✨ Success! Uploaded 13 files (120 already uploaded) (1.22 sec)

Total Upload: 16240.27 KiB / gzip: 2635.56 KiB
Your worker has access to the following bindings:
- Durable Objects:
  - NEXT_CACHE_DO_QUEUE: DurableObjectQueueHandler (defined in .open-next/worker.js)
- KV Namespaces:
  - NEXT_CACHE_WORKERS_KV: ....
- D1 Databases:
  - NEXT_TAG_CACHE_D1: OpennextTagCache (...)
- Services:
  - WORKER_SELF_REFERENCE: ...
- Assets:
  - Binding: ASSETS
- Vars:
  - VAR: "..."

✘ [ERROR] A request to the Cloudflare API (/accounts/.../workers/scripts/...) failed.

  Cannot create binding for class in script '.open-next/worker.js' that does not exist. [code: 10061]
  
  If you think this is a bug, please open an issue at: https://github.com/cloudflare/workers-sdk/issues/new/choose


ERROR Wrangler command failed
 ELIFECYCLE  Command failed with exit code 1.
Failed: error occurred while running deploy command

If that could be useful the project is a monorepo and the Next.js website is inside the web folder. I Already tried using script_name = "web/.open-next/worker.js" and that doesn't work either.

@conico974
Copy link
Collaborator

@ibobo use the name of your app, not .open-next/worker.js

@ibobo
Copy link

ibobo commented Apr 2, 2025

@conico974 Thank you, it works that way.

For anyone looking into this:

name = "app_name"

#...

[[durable_objects.bindings]]
name = "NEXT_CACHE_DO_QUEUE"
class_name = "DurableObjectQueueHandler"
script_name = "app_name"

@vicb
Copy link
Contributor

vicb commented Apr 5, 2025

@ibobo you shouldn't need script_name when you use the most recent wrangler

@ibobo
Copy link

ibobo commented Apr 9, 2025

@ibobo you shouldn't need script_name when you use the most recent wrangler

I confirm now script_name is not needed anymore. Thanks.

@vicb vicb closed this as completed Apr 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants