Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

cf deploy: Python Workers fail with 'No module named workers' because vendored modules are uploaded as ./python_modules/...

オープン 初心者向け
#392 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@MattieTK がすでに取り組んでいます。

2026年10月22日 から。

  • #393 @MattieTK による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
76/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python, typescript
領域
backend, cli

調査の方向性

issue では、公開済みバンドル dist/deploy-input-*.mjs 内のモジュールアップロードループが指摘されています。リポジトリ内でそのソースを見つけ、テストでアップロードするモジュール名がカバーされているか確認してください。cf deploy が送信する名前を、マニフェストのキーおよびここで説明されている正常に動作する Wrangler の挙動と比較してください。完了条件は、Python Worker がデプロイ後に vendored の workers SDK をインポートできることです。また、Rust の例も引き続きデプロイできるか確認してください。

索引モデルが issue の本文から書いたものです。

説明

Summary of the issue

After migrating a working pywrangler project with cf migrate, cf deploy fails for Python Workers that import the Workers SDK (from workers import ...).

The migration itself works. cf migrate reports no follow-ups and writes a correct cloudflare.config.ts (python_workers flag, src/entry.py entrypoint), and cf deploy then builds the project with the same modules as Wrangler. The failure comes at upload: the version is rejected with 10021 ModuleNotFoundError: No module named 'workers'. The same project deploys fine with pywrangler deploy. The bug is in how cf deploy names modules in the upload, not in the migration or the config.

Root cause: cf deploy uploads every non-entrypoint module as ./<path>, where Wrangler uploads <path>. Python Workers' vendored packages must be named python_modules/...; as ./python_modules/..., the runtime doesn't add them to site-packages, so the external workers SDK (workers-runtime-sdk, vendored by pywrangler sync) can't be imported.

I captured both tools' uploads against a local fake API (CLOUDFLARE_API_BASE_URL). Both send PUT /accounts/:id/workers/scripts/:name, and the parts have identical content, sizes and content types. The only meaningful difference is the part names:

Wrangler / pywrangler (works) cf (fails)
main module entry.py entry.py
vendored SDK python_modules/workers/__init__.py ./python_modules/workers/__init__.py
other vendored files python_modules/_workers_sdk_patch_loader.pth, ... ./python_modules/_workers_sdk_patch_loader.pth, ...

The Build Output manifest (.cloudflare/output/v0/workers/default/worker.config.json) is correct: its keys are python_modules/... without a prefix. The ./ is added when cf deploy turns the manifest into upload modules. In the published 1.0.0-beta.20 bundle (dist/deploy-input-*.mjs, de-minified):

for (const [name, mod] of Object.entries(manifest.modules)) {
  if (name === mainModule) continue;
  // ...
  modules.push({ name: `./${name}`, filePath, content, type: moduleTypes[mod.type] });
}

Proposed fix: use the manifest key as the module name, as Wrangler does:

-  modules.push({ name: `./${name}`, filePath, content, type: moduleTypes[mod.type] });
+  modules.push({ name, filePath, content, type: moduleTypes[mod.type] });

I verified this by making that one-line change in a local copy of cf 1.0.0-beta.20 and deploying for real:

Worker Unpatched cf Patched cf
Python hello world (vendored workers SDK) 400, 10021 No module named 'workers' Deployed; GET / returns 200 Hello from a Python Worker
Rust hello world (worker-build, Wasm + JS shim) Deployed, 200 Deployed; GET / returns 200 Hello from a Rust Worker (no regression)

Not tested: a JS/TS Worker with additional modules, and Python Workers with third-party packages beyond the SDK. If the ./ is needed for JS in some case, a narrower fix is to skip the prefix for python_modules/ paths only. I'm happy to open a PR with the fix and a test if that would help.

Related: #56 covers Python support in cf dev. This issue is about cf deploy, which otherwise already handles Python projects that pywrangler sync has prepared.

Not platform-specific: the prefix is a hard-coded string. I reproduced the same upload names on Linux (WSL2, Ubuntu 22.04, Node 24.22.1): 32 of 33 module parts are ./-prefixed, with only the entrypoint unprefixed.

Expected behaviour

cf deploy uploads a Python Worker with vendored packages the same way pywrangler deploy does, with module names exactly as in the Build Output manifest, and the Worker can import the workers SDK.

Version of cf used

1.0.0-beta.20

System information and package versions
  System:
    OS: Windows 11 10.0.26200
    CPU: (24) x64 12th Gen Intel(R) Core(TM) i9-12900F
    Memory: 22.58 GB / 63.82 GB
  Binaries:
    Node: 22.21.1 - %USERPROFILE%\AppData\Local\Volta\tools\image\node\22.21.1\node.EXE
    npm: 10.9.4 - %USERPROFILE%\AppData\Local\Volta\tools\image\node\22.21.1\npm.CMD
    bun: 1.3.5 - %USERPROFILE%\.bun\bin\bun.EXE
  npmPackages:
    cf: ^1.0.0-beta.20 => 1.0.0-beta.20
    wrangler: 4.152.0 => 4.152.0

Also: workers-py (pywrangler) 1.17.8, vendored workers-runtime-sdk 1.9.5, uv 0.13.5. Reproduced on Linux as described above.

Reproduction (optional)

src/entry.py:

from workers import Response, WorkerEntrypoint


class Default(WorkerEntrypoint):
    async def fetch(self, request):
        return Response("Hello from a Python Worker")

wrangler.jsonc:

{
  "name": "cf-python-repro",
  "main": "src/entry.py",
  "compatibility_date": "2026-10-01",
  "compatibility_flags": ["python_workers"]
}

pyproject.toml: dependencies = [], dev dependency group ["workers-py", "workers-runtime-sdk"]. package.json: devDependency [email protected].

npm install
uv run pywrangler sync   # populates python_modules/ (workers SDK 1.9.5 + helpers)
cf migrate               # "Migration complete", no follow-up items
cf deploy                # builds 32 modules (111.15 KiB vendored), then fails with 10021

Control: with the same files, deleting .cloudflare/output and running uv run pywrangler deploy succeeds, and the Worker returns 200 Hello from a Python Worker.

Side note: after any cf build/cf deploy, wrangler deploy refuses to run until .cloudflare/output is deleted ("Cloudflare Build Output was found at .cloudflare/output"). That's a reasonable safeguard, but combined with this bug, Python users who fall back to pywrangler hit it straight away.

Relevant error logs (optional)
[10021] Uncaught Error: PythonError: Traceback (most recent call last):
  File "/lib/python314.zip/_pyodide/_base.py", line 523, in eval_code
  File "/lib/python314.zip/_pyodide/_base.py", line 357, in run
  File "<exec>", line 9, in <module>
  File "/lib/python314.zip/_pyodide/_base.py", line 666, in pyimport_impl
  File "/session/metadata/entry.py", line 1, in <module>
    from workers import Response, WorkerEntrypoint
  File "/lib/python3.14/site-packages/workers/__init__.py", line 3, in <module>
ModuleNotFoundError: No module named 'workers'
You need to update to workers-py >= 1.9 or to pass disable_python_external_sdk
 [code: 10021]
400 Bad Request

(The "update to workers-py >= 1.9" hint is misleading here: workers-py 1.17.8 is installed, and the same python_modules/ deploys fine through pywrangler.)

主要言語
TypeScript
スター
916
フォーク
53
平均マージ
19時間 13分
マージ済み PR(30日)
185

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

cloudflare/cf のほかの issue

cloudflare/cf の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。