Skip to content

Workers Builds: dashboard shows non-production builds enabled but preview trigger is not created #15140

Description

@andywarren

What versions & operating system are you using?

Requested envinfo output:

System:
OS: macOS 26.5.2
CPU: (16) x64 Intel(R) Core(TM) i7-10700K CPU @ 3.80GHz
Memory: 1.52 GB / 32.00 GB
Shell: 5.8 - /usr/local/bin/zsh

Binaries:
Node: 22.22.2 - /Users/Andy/.nvm/versions/node/v22.22.2/bin/node
npm: 10.9.7 - /Users/Andy/.nvm/versions/node/v22.22.2/bin/npm
pnpm: 9.15.9 - /Users/Andy/Library/pnpm/pnpm

The affected Workers Builds jobs ran with:
Node: 24.18.0
pnpm: 9.15.9
Wrangler: 4.88.0

Please provide a link to a minimal reproduction

N/A — this is a Workers Builds backend-state synchronization issue rather than an application-code issue. The affected repository is private. Complete reproduction steps and before/after Workers Builds API evidence are provided below. I can provide affected account, Worker, repository, trigger, connection, and build identifiers privately to Cloudflare staff.

Describe the Bug

Summary

While migrating an existing Worker from a dedicated development Worker to Workers Builds branch previews, the Cloudflare dashboard showed Builds for non-production branches enabled, but pushes to non-production GitHub branches produced no builds at all.

The Workers Builds API revealed that only the production trigger existed. The preview/non-production trigger had never been created despite the dashboard showing non-production builds as enabled.

Manually creating the missing preview trigger through the Workers Builds API immediately fixed both manual preview builds and automatic GitHub branch builds.

Environment

The affected configuration was:

Git provider: GitHub
Repository: private repository owned by a GitHub Organization

Production branch: main
Build command: pnpm run build
Production deploy command: npx wrangler versions upload
Non-production deploy command: npx wrangler versions upload

pnpm: 9.15.9
Workers Builds Node: 24.18.0
Wrangler: 4.88.0

workers_dev: false
preview_urls: true

The repository had recently been transferred from a personal GitHub account to a GitHub Organization. The Worker Git integration was disconnected and then reconnected to the transferred repository.

The GitHub repository itself retained the same repository identity through the transfer.

Steps to reproduce

  1. Start with an existing Worker connected to a GitHub repository through Workers Builds.

  2. Transfer the GitHub repository from a personal GitHub account to a GitHub Organization.

  3. Disconnect the Git repository from the existing Worker in Cloudflare.

  4. Reconnect the Worker to the transferred repository under the GitHub Organization.

  5. Set the production branch to main.

  6. Enable Builds for non-production branches in the Cloudflare dashboard.

  7. Configure:

    Build command:
    pnpm run build
    
    Production deploy:
    npx wrangler versions upload
    
    Non-production/version command:
    npx wrangler versions upload
    
    Build watch paths:
    *
    
  8. Push commits containing real file changes to a non-production branch.

  9. Observe that no Workers Build is created.

I also tested empty commits. Neither real file changes nor empty commits created a non-production build.

The dashboard continued to show Builds for non-production branches as enabled.

Expected behavior

Enabling Builds for non-production branches should create/configure a preview Workers Builds trigger equivalent to:

{
  "branch_includes": ["*"],
  "branch_excludes": ["main"],
  "build_command": "pnpm run build",
  "deploy_command": "npx wrangler versions upload"
}

A matching GitHub push should invoke that trigger and create the non-production build and branch/commit preview.

The dashboard should not report non-production builds as enabled unless the corresponding backend trigger actually exists.

Actual behavior

The dashboard showed non-production builds as enabled, but pushes to non-production branches silently produced:

  • no Build History entry;
  • no Cloudflare GitHub check;
  • no Cloudflare pull-request comment;
  • no commit Preview URL;
  • no branch Preview Alias URL.

A Deploy Hook targeting the non-production branch also failed with Cloudflare error 12001 Internal server error.

A Deploy Hook targeting main, however, worked normally. It cloned the same repository, installed the same dependencies, ran the same build command, and successfully uploaded a Worker candidate version.

This ruled out:

  • GitHub repository access;
  • the GitHub App installation;
  • repository cloning;
  • the Workers Builds API token;
  • dependency installation;
  • the build command;
  • the Wrangler upload command;
  • the Worker itself.

Workers Builds API diagnosis

I queried:

GET /accounts/{account_id}/builds/workers/{external_script_id}/triggers

Despite the dashboard showing non-production builds enabled, the API returned only one trigger, for production:

{
  "trigger_uuid": "<redacted>",
  "build_command": "pnpm run build",
  "deploy_command": "npx wrangler versions upload",
  "branch_includes": ["main"],
  "branch_excludes": []
}

There was no second preview/non-production trigger.

This was the root cause.

Workaround

I manually created the missing trigger through the Workers Builds API with the equivalent of:

{
  "trigger_name": "Deploy non-production branches",
  "build_command": "pnpm run build",
  "deploy_command": "npx wrangler versions upload",
  "root_directory": "/",
  "branch_includes": ["*"],
  "branch_excludes": ["main"],
  "path_includes": ["*"],
  "path_excludes": []
}

Afterward the Workers Builds API correctly returned two triggers:

Production trigger
  branch_includes: ["main"]
  branch_excludes: []

Preview trigger
  branch_includes: ["*"]
  branch_excludes: ["main"]

Result after workaround

Immediately after creating the missing preview trigger:

  1. Manually invoking that trigger against the existing feature branch successfully queued a build.
  2. Cloudflare cloned and built the correct branch.
  3. Wrangler successfully uploaded a Worker preview version.
  4. Cloudflare generated both a version-specific Preview URL and a stable branch Preview Alias URL.
  5. A subsequent ordinary GitHub push automatically triggered Workers Builds without any manual API invocation.
  6. The cloudflare-workers-and-pages GitHub bot posted a successful deployment comment containing both preview URLs.
  7. After merging the feature branch, an ordinary main push also triggered the existing production Workers Builds trigger and uploaded a candidate Worker version without automatically changing production traffic.

No additional GitHub App permission change, repository reconnect, Worker configuration change, or build-command change was required after manually creating the missing preview trigger.

Impact

The issue was particularly difficult to diagnose because the Cloudflare dashboard represented the configuration as valid:

Builds for non-production branches: Enabled

while the corresponding preview trigger did not exist in the Workers Builds backend.

There was no dashboard warning or validation error indicating this mismatch.

GitHub pushes simply disappeared from the perspective of Workers Builds, while a branch-targeted Deploy Hook returned only the generic 12001 Internal server error.

The dashboard/backend state mismatch was the core defect.

Suggested fixes

  • Make enabling Builds for non-production branches transactionally create and verify the preview trigger.
  • Derive the dashboard checkbox state from the actual existence/configuration of the preview trigger rather than independent saved UI state.
  • If the preview trigger is missing or invalid, display a warning rather than showing non-production builds as enabled.
  • Add a dashboard action to repair/recreate a missing preview trigger.
  • Return a more specific error than 12001 Internal server error when a non-production Deploy Hook cannot execute because the corresponding Workers Builds trigger does not exist.
  • Validate/recreate production and preview triggers when a connected repository is transferred, disconnected/reconnected, or changes GitHub installation target.

Additional context

This occurred during a repository transfer from a personal GitHub account to a GitHub Organization.

The GitHub App had correct access to the organization and repository. The production Workers Builds trigger continued to function. The defect was isolated specifically to the missing preview/non-production trigger.

I can provide the affected Cloudflare account ID, Worker tag, trigger UUIDs, repository connection UUID, build-token UUID, build UUIDs, exact timestamps, and other backend identifiers privately to Cloudflare staff if needed.

Please provide any relevant error logs

Non-production Deploy Hook failure before repair

A Deploy Hook targeting the affected non-production branch returned:

{
  "success": false,
  "messages": [],
  "errors": [
    {
      "code": 12001,
      "message": "Internal server error"
    }
  ],
  "result": null
}

A Deploy Hook targeting main succeeded using the same repository and Workers Builds configuration.

Workers Builds API state before repair

The following endpoint was queried:

GET /accounts/{account_id}/builds/workers/{external_script_id}/triggers

It returned only the production trigger:

{
  "trigger_uuid": "<redacted>",
  "build_command": "pnpm run build",
  "deploy_command": "npx wrangler versions upload",
  "branch_includes": ["main"],
  "branch_excludes": []
}

No trigger with:

{
  "branch_includes": ["*"],
  "branch_excludes": ["main"]
}

existed, despite the dashboard displaying:

Builds for non-production branches: Enabled

State after workaround

After creating the missing preview trigger through the Workers Builds API, the trigger list contained:

Production trigger
  branch_includes: ["main"]
  branch_excludes: []

Preview trigger
  branch_includes: ["*"]
  branch_excludes: ["main"]

Manual invocation of the newly created preview trigger succeeded.

A subsequent ordinary GitHub push then automatically created a successful Workers Build and produced both a commit Preview URL and stable branch Preview Alias URL.

No GitHub App permission change, repository reconnect, Worker code change, or build-command change was required after creating the missing trigger.

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature:workers-buildsRelating to Workers Builds: https://developers.cloudflare.com/workers/ci-cd/#workers-builds

    Type

    Projects

    Status
    In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions