Workers SDK Issue Reports

← Back to Dashboard

#8269 `yarn wrangler init --from-dash` broken

Download Reproduction
Recommendation:KEEP OPEN
Difficulty:easy
Reasoning:

Bug reproduced on wrangler 4.60.0 + Yarn Classic 1.22.22. Yarn Classic cannot handle version specifiers with ^ in `yarn create` commands - tries to execute binary with version in path.

Suggested Action:

Fix version specifier handling for Yarn Classic in init.ts C3 delegation

Analysis Report

Issue Review: cloudflare/workers-sdk#8269

Summary

yarn wrangler init --from-dash fails because Yarn Classic (v1.x) doesn't support version specifiers with special characters like ^ in yarn create commands.

Findings

  • Created: 2025-02-26
  • Updated: 2025-10-30
  • Version: wrangler 3.110.0 / c3 v2.38.2 -> wrangler 4.60.0 / c3 2.62.3
  • Component: Wrangler / C3 (packages/wrangler/src/init.ts)
  • Labels: bug, c3, c3-e2e
  • Comments: 0

Key Evidence

  1. Bug Reproduced: Running yarn wrangler init --from-dash <name> with Yarn Classic (v1.22.22) and wrangler 4.60.0 fails with:

    /bin/sh: /Users/.../.yarn/bin/create-cloudflare@^2.5.0: No such file or directory
    error Command failed. Exit code: 127
    
  2. Root Cause Identified: The WRANGLER_C3_COMMAND defaults to create cloudflare@^2.5.0 (in packages/workers-utils/src/environment-variables/misc-variables.ts:35). When wrangler detects yarn as the package manager, it runs:

    yarn create cloudflare@^2.5.0 <name> --existing-script <name>
    

    Yarn Classic correctly installs create-cloudflare@2.62.3, but then attempts to execute a binary named create-cloudflare@^2.5.0 (with the version specifier in the path), which doesn't exist.

  3. npm Works Correctly: The same command with npm (npm create cloudflare@^2.5.0) works as expected because npm properly handles version specifiers in create commands.

  4. No Fix Found:

    • No merged PRs reference fixing issue #8269
    • Issue not mentioned in changelogs for wrangler or create-cloudflare
    • The problematic code still exists in the current codebase

Recommendation

Status: KEEP OPEN

Reasoning: The bug is reproducible with current versions (wrangler 4.60.0, Yarn Classic 1.22.22). This is a compatibility issue between wrangler's C3 delegation logic and Yarn Classic's yarn create command behavior. The error message in the original report differs slightly from current reproduction (package.json error vs binary path error), but the underlying issue is the same: Yarn Classic cannot properly handle version specifiers with ^ in yarn create commands.

Action: Fix the version specifier handling for Yarn Classic, or use a different approach for delegating to C3 when yarn is detected.

Root Cause Analysis

Code Flow

  1. User runs yarn wrangler init --from-dash <worker-name>
  2. Wrangler detects yarn as package manager via getPackageManager() in packages/wrangler/src/package-manager.ts
  3. Wrangler constructs C3 arguments in packages/wrangler/src/init.ts:57-65:
    const c3Arguments = [
        ...shellquote.parse(getC3CommandFromEnv()),  // Returns ["create", "cloudflare@^2.5.0"]
        ...(name ? [name] : []),
        ...(yesFlag && isNpm(packageManager) ? ["-y"] : []),
        ...(isNpm(packageManager) ? ["--"] : []),
        ...(args.fromDash ? ["--existing-script", args.fromDash] : []),
        ...(yesFlag ? ["--wrangler-defaults"] : []),
    ];
    
  4. Wrangler executes execa(packageManager.type, c3Arguments) which becomes:
    yarn create cloudflare@^2.5.0 <name> --existing-script <name>
    
  5. Yarn Classic installs create-cloudflare but tries to run /path/.yarn/bin/create-cloudflare@^2.5.0 which doesn't exist

Problem Location

  • File: packages/workers-utils/src/environment-variables/misc-variables.ts

  • Line: 35

  • Code:

    export const getC3CommandFromEnv = getEnvironmentVariableFactory({
        variableName: "WRANGLER_C3_COMMAND",
        defaultValue: () => "create cloudflare@^2.5.0",
    });
    
  • File: packages/wrangler/src/init.ts

  • Lines: 57-65, 139-150

  • Issue: No special handling for Yarn Classic's inability to parse version specifiers with ^

Proposed Solution

Option 1: Strip version specifier for Yarn Classic (Recommended)

Modify the C3 argument construction to handle Yarn Classic specially:

// In packages/wrangler/src/init.ts

function getC3Arguments(packageManager: PackageManager, name: string | undefined, yesFlag: boolean, fromDash: string | undefined): string[] {
    let c3Command = shellquote.parse(getC3CommandFromEnv());
    
    // Yarn Classic (v1.x) doesn't properly handle version specifiers with ^ in yarn create
    // It installs the package correctly but fails to find the binary with the version in the path
    if (packageManager.type === 'yarn') {
        c3Command = c3Command.map(arg => {
            // Convert "cloudflare@^2.5.0" to "cloudflare" for yarn
            // Yarn will install the latest version that satisfies the constraint anyway
            if (typeof arg === 'string' && arg.includes('@^')) {
                return arg.replace(/@\^[\d.]+$/, '');
            }
            return arg;
        });
    }
    
    return [
        ...c3Command,
        ...(name ? [name] : []),
        ...(yesFlag && isNpm(packageManager) ? ["-y"] : []),
        ...(isNpm(packageManager) ? ["--"] : []),
        ...(fromDash ? ["--existing-script", fromDash] : []),
        ...(yesFlag ? ["--wrangler-defaults"] : []),
    ];
}

Option 2: Use yarn dlx instead of yarn create

For Yarn, use yarn dlx create-cloudflare@^2.5.0 instead of yarn create cloudflare@^2.5.0. The dlx command handles version specifiers correctly.

// Modify the command construction for yarn
if (packageManager.type === 'yarn') {
    // Use dlx for yarn to properly handle version specifiers
    const c3Package = getC3CommandFromEnv().replace('create ', ''); // "cloudflare@^2.5.0"
    return execa('yarn', ['dlx', `create-${c3Package}`, ...otherArgs]);
}

Note: yarn dlx requires Yarn 2+ (Berry). For Yarn Classic, the version stripping approach (Option 1) is more appropriate.

Option 3: Change default to use exact version

Change the default WRANGLER_C3_COMMAND from create cloudflare@^2.5.0 to create cloudflare@2 (major version only), which is more compatible across package managers.

Implementation Difficulty

Difficulty: Easy

Justification:

  • Single file change (or two files for Option 1)
  • Well-isolated code path
  • Clear root cause and solution
  • No breaking changes expected
  • Existing test infrastructure for C3 integration

Files to Modify

  1. packages/wrangler/src/init.ts - Add yarn-specific handling for version specifiers
  2. packages/workers-utils/src/environment-variables/misc-variables.ts - (Optional) Update default command if using Option 3

Testing Recommendations

  1. Manual Testing:

    • Test yarn wrangler init --from-dash <worker> with Yarn Classic (v1.x)
    • Test yarn wrangler init <name> with Yarn Classic
    • Verify npm, pnpm, and bun still work correctly
  2. Unit Tests:

    • Add test cases in packages/wrangler/src/__tests__/init.test.ts for yarn version specifier handling
  3. E2E Tests:

    • The c3-e2e label suggests e2e tests exist - ensure they cover yarn scenarios
    • Add specific test for --from-dash with yarn if not present
  4. Cross-Package Manager Testing:

    • Test with Yarn Classic (1.x)
    • Test with Yarn Berry (2.x+)
    • Verify npm, pnpm, bun continue to work

Notes & Feedback (0)

No notes yet.

Add Note