Azure / Azure/static-web-apps-cli
[Bug] `downloadCoreTools` fails with `ENOENT: chmod 'gozip'` because current Core Tools releases no longer ship `gozip`
- Dominant language
- TypeScript
- Stars
- 668
- Forks
- 156
- PR merge metrics
- No merged PRs in 30d
Description
Before filing this issue, please ensure you're using the latest CLI by running `swa --version` and comparing to the latest version on [npm](https://www.npmjs.com/package/@azure/static-web-apps-cli).
I am using `@azure/static-web-apps-cli` **2.0.10**, which is the latest version on npm at the time of writing.
**Are you accessing the CLI from the default port `:4280` ?**
- [ ] No, I am using a different port number (`--port`) and accessing the CLI from that port
- [x] Yes, I am accessing the CLI from port `:4280`
(Note: the failure occurs during startup, before the emulator begins listening, so the port is not a factor in this bug.)
**ℹ️ NOTE: Make sure to enable debug logs when running any `swa` commands using `--verbose=silly`**
Verbose log (user-specific paths and names redacted as <user>, <project-root>, etc.)
```
Welcome to Azure Static Web Apps CLI (2.0.10)
Getting config file options from "swa-cli.config.json"...
Config file does not exist at "swa-cli.config.json"
***********************************************************************
* WARNING: This emulator may not match the cloud environment exactly. *
* Always deploy and test your app in Azure. *
***********************************************************************
Checking if localhost:4280 is accepting TCP connections...
Port 4280 is available. Use it.
Resolved port number: 4280
appDevserverUrl provided, we will try connect to dev server at .
Api Folder found: /home///api
Trying to read workflow config with values:
- appLocation: /home//
- outputLocation: http://localhost:
- apiLocation: /home///api
Found a SWA workflow file: /home///.github/workflows/azure-static-web-apps-.yml
Error reading workflow configuration:
missing property "jobs.build_and_deploy_job" in the SWA workflow file "/home///.github/workflows/azure-static-web-apps-.yml".
See https://docs.microsoft.com/azure/static-web-apps/build-configuration?tabs=github-actions#build-configuration for more information.
✖ Failed to download Functions Core Tools v4.
✖ Error: ENOENT: no such file or directory, chmod '/home//.swa/core-tools/v4/gozip'
Error: ENOENT: no such file or directory, chmod '/home//.swa/core-tools/v4/gozip'
at Object.chmodSync (node:fs:2050:11)
at downloadCoreTools (file:///home//.npm/_npx//node_modules/@azure/static-web-apps-cli/src/core/func-core-tools.ts:257:8)
at processTicksAndRejections (node:internal/process/task_queues:104:5)
at getCoreToolsBinary (file:///home//.npm/_npx//node_modules/@azure/static-web-apps-cli/src/core/func-core-tools.ts:290:5)
at start (file:///home//.npm/_npx//node_modules/@azure/static-web-apps-cli/src/cli/commands/start/start.ts:182:26)
at Command. (file:///home//.npm/_npx//node_modules/@azure/static-web-apps-cli/src/cli/commands/start/register.ts:75:7)
at Command.parseAsync (/home//.npm/_npx//node_modules/commander/lib/command.js:935:5)
at run (file:///home//.npm/_npx//node_modules/@azure/static-web-apps-cli/src/cli/index.ts:98:3) {
errno: -2,
code: 'ENOENT',
syscall: 'chmod',
path: '/home//.swa/core-tools/v4/gozip'
}
✖
Could not find or install Azure Functions Core Tools.
Install Azure Functions Core Tools with:
npm i -g azure-functions-core-tools@4 --unsafe-perm true
See https://aka.ms/functions-core-tools for more information.
```
Note: the "Error reading workflow configuration" warning above comes from my local workflow file and is unrelated to this bug — the same `ENOENT: chmod 'gozip'` failure reproduces with the minimal steps below, without any workflow file.
**Describe the bug**
When `swa start` is run with `--api-location`, the CLI calls `getCoreToolsBinary()`, which downloads Azure Functions Core Tools if no usable installation is found. After the package is downloaded and unzipped successfully, `downloadCoreTools()` (`src/core/func-core-tools.ts`) unconditionally runs `chmodSync` on a file named `gozip` on Linux/macOS. Current Core Tools releases no longer include `gozip`, so the call throws `ENOENT` and the entire startup fails — even though the `func` binary itself was downloaded and extracted correctly.
Root cause details are in **Additional context** below.
**To Reproduce**
Steps to reproduce the behavior (minimal reproduction — the failure is independent of any project contents, because it happens inside `downloadCoreTools` before the API is ever started):
1. Use a Linux x64 machine (Ubuntu, Node.js v24) where the `func` binary is not detected globally
2. Remove any cached Core Tools: `rm -rf ~/.swa/core-tools`
3. Create an empty directory to pass as the API location: `mkdir -p app api`
4. Run: `npx @azure/static-web-apps-cli@2.0.10 start ./app --api-location ./api`
5. The CLI attempts to download Functions Core Tools v4 and fails with `ENOENT: no such file or directory, chmod '~/.swa/core-tools/v4/gozip'`
**Expected behavior**
- Startup should succeed as long as `func` itself was downloaded and extracted correctly, even if `gozip` is absent. For the local development scenario covered by `swa start`, `gozip` was a packaging/deployment helper and should not be required.
- At minimum, the code should check whether the file exists (e.g. `fs.existsSync`) before calling `chmodSync`, and skip (or log a warning) if it does not.
**Screenshots**
N/A — see the error log above.
**Desktop (please complete the following information):**
- OS: Ubuntu (Linux x64)
- Node.js: v24.18.0
- `@azure/static-web-apps-cli`: 2.0.10
- `azure-functions-core-tools` (installed via npm, for reference): 4.13.0
**Additional context**
*Root cause (investigated):*
`gozip` is **no longer included** in current `azure-functions-core-tools` releases — neither in the npm distribution (4.13.0) nor in the full `linux-x64` archive (4.12.1) downloaded directly from GitHub Releases. I inspected the extracted archives: there is no file named `gozip`; instead they ship `System.IO.Compression.ZipFile.dll` (the standard .NET compression library). It appears the Core Tools team replaced the external Go binary (`gozip`) used for packaging with the standard .NET library.
However, `downloadCoreTools` still assumes `gozip` exists and chmods it unconditionally on Linux/macOS (current `main`, `src/core/func-core-tools.ts`):
```ts
// Fix permissions on MacOS/Linux
if (os.platform() === "linux" || os.platform() === "darwin") {
fs.chmodSync(path.join(dest, "func"), 0o755);
fs.chmodSync(path.join(dest, "gozip"), 0o755); // <-- throws ENOENT
}
```
*Suggested fix:*
Guard the `chmodSync` call on `gozip` with an existence check:
```ts
const gozipPath = path.join(dest, "gozip");
if (fs.existsSync(gozipPath)) {
fs.chmodSync(gozipPath, 0o755);
}
```
*Related issue:*
#899 is a past case where the download flow broke because assumptions about the distribution feed/artifacts no longer held (Windows, missing `size: "full"` artifact). This report is a different, newer cause: the removal of `gozip` itself from the shipped artifacts.
*Workaround:*
Skip the automatic Core Tools startup entirely: start Azure Functions Core Tools separately with `func start`, then connect the SWA CLI to it:
```
swa start --api-devserver-url
```
This corresponds to the "Manual start" flow in the [official docs](https://learn.microsoft.com/azure/static-web-apps/static-web-apps-cli-api-server#manual-start) and does not go through `downloadCoreTools`, so it is unaffected by this bug.
Contributor guide
Research direction
Start in src/core/func-core-tools.ts at downloadCoreTools(), then reproduce with the listed npx command after removing ~/.swa/core-tools. Verify startup succeeds when the extracted Core Tools contain func but not gozip, while existing permission handling remains intact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100