#8269 `yarn wrangler init --from-dash` broken
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.
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
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: 127Root Cause Identified: The
WRANGLER_C3_COMMANDdefaults tocreate cloudflare@^2.5.0(inpackages/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 namedcreate-cloudflare@^2.5.0(with the version specifier in the path), which doesn't exist.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.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
- User runs
yarn wrangler init --from-dash <worker-name> - Wrangler detects yarn as package manager via
getPackageManager()inpackages/wrangler/src/package-manager.ts - 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"] : []), ]; - Wrangler executes
execa(packageManager.type, c3Arguments)which becomes:yarn create cloudflare@^2.5.0 <name> --existing-script <name> - Yarn Classic installs
create-cloudflarebut tries to run/path/.yarn/bin/create-cloudflare@^2.5.0which doesn't exist
Problem Location
File:
packages/workers-utils/src/environment-variables/misc-variables.tsLine: 35
Code:
export const getC3CommandFromEnv = getEnvironmentVariableFactory({ variableName: "WRANGLER_C3_COMMAND", defaultValue: () => "create cloudflare@^2.5.0", });File:
packages/wrangler/src/init.tsLines: 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
packages/wrangler/src/init.ts- Add yarn-specific handling for version specifierspackages/workers-utils/src/environment-variables/misc-variables.ts- (Optional) Update default command if using Option 3
Testing Recommendations
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
- Test
Unit Tests:
- Add test cases in
packages/wrangler/src/__tests__/init.test.tsfor yarn version specifier handling
- Add test cases in
E2E Tests:
- The
c3-e2elabel suggests e2e tests exist - ensure they cover yarn scenarios - Add specific test for
--from-dashwith yarn if not present
- The
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.