Azure / Azure/static-web-apps-cli

[Bug] `downloadCoreTools` fails with `ENOENT: chmod 'gozip'` because current Core Tools releases no longer ship `gozip`

Open Beginner friendly
#1,007 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.