Managed Node v4 API returns 404 with root npm workspace and non-empty devDependencies
- Dominant language
- No language data
- Stars
- 346
- Forks
- 67
- PR merge metrics
- No merged PRs in 30d
Description
### Describe the bug
A managed Azure Static Web Apps API using the Node.js v4 programming model deploys successfully, but all API routes return HTTP 404 when the repository root `package.json` declares npm `workspaces` including the API package and has a non-empty root `devDependencies` object.
The same stock API routes correctly when either of those conditions is removed:
- Root `workspaces` absent: API works.
- Root `workspaces: ["api"]` present but no root `devDependencies`: API works.
- Root `workspaces: ["api"]` present with `devDependencies: {}`: API works.
- Root `workspaces: ["api"]` present with one root devDependency: API returns 404.
This looks like an SWA/Oryx packaging or managed Functions indexing issue. The deployment logs report success and show the API was built and uploaded, but the deployed SWA behaves as if no Function routes were indexed.
### Minimal repro
Start from the stock no-framework SWA + Node v4 API example shape:
```text
.github/workflows/deploy.yml
src/index.html
src/styles.css
api/host.json
api/package.json
api/package-lock.json
api/src/functions/message.js
api/src/index.js
```
Use this root `package.json`:
```json
{
"name": "swa-workspace-repro",
"private": true,
"workspaces": [
"api"
],
"devDependencies": {
"azurite": "^3.35.0"
}
}
```
Use this `api/package.json`:
```json
{
"name": "api",
"version": "1.0.0",
"description": "",
"main": "src/functions/*.js",
"scripts": {
"start": "func start"
},
"dependencies": {
"@azure/functions": "^4.0.0"
}
}
```
Use this `api/src/functions/message.js`:
```js
const { app } = require("@azure/functions");
app.http("message", {
methods: ["GET", "POST"],
authLevel: "anonymous",
handler: async (request, context) => {
return { body: JSON.stringify({ text: "Hello, from the API!" }) };
},
});
```
Use a standard SWA deploy workflow with `app_location: src` and `api_location: api`:
```yaml
name: Build, verify & deploy
on:
pull_request:
types: [opened, synchronize, reopened, closed]
branches: [main]
jobs:
build_and_deploy:
if: github.event_name == 'pull_request' && github.event.action != 'closed'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build And Deploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
repo_token: ${{ secrets.GITHUB_TOKEN }}
action: upload
app_location: src
api_location: api
```
### Expected behavior
After a successful deployment:
```text
GET /api/message -> 200 {"text":"Hello, from the API!"}
```
### Actual behavior
The GitHub Actions deployment succeeds, the static frontend is served, but the API route is missing:
```text
GET / -> 200
GET /api/message -> 404
```
The deploy log still shows the API being built and uploaded. Representative lines from the successful deployment:
```text
Api Directory Location: 'api' was found.
Source directory : /github/workspace/api
Running 'npm install --production'...
Running 'npm install'...
Function Runtime Information. OS: linux, Functions Runtime: ~4, node version: 22
Zipping Api Artifacts
Done Zipping Api Artifacts
Deployment Complete :)
```
### Controls tested
The following controls were tested against the same SWA preview environment:
| Root package shape | Result |
| --- | --- |
| No root `package.json` stock example | `/api/message` 200 |
| Root `package.json` with `workspaces: ["api"]`, no root `devDependencies` | `/api/message` 200 |
| Root `package.json` with `workspaces: ["api"]`, empty `devDependencies: {}` | `/api/message` 200 |
| Root `package.json` with `workspaces: ["api"]`, `devDependencies: { "azurite": "^3.35.0" }` | `/api/message` 404 |
| Root `package.json` with `workspaces: ["api"]`, `devDependencies: { "@azure/static-web-apps-cli": "^2.0.2" }` | `/api/message` 404 |
So the repro does not appear to be specific to `azurite` or `@azure/static-web-apps-cli`; the trigger appears to be the combination of npm workspaces including the API package plus a non-empty root `devDependencies` object.
### Environment
- Azure Static Web Apps managed API
- `Azure/static-web-apps-deploy@v1`
- SWA region used in repro: West Europe
- PR preview environment
- Oryx selected Node.js `22.22.0`
- Functions runtime reported as `~4`
- API uses `@azure/functions` v4 programming model
### Why this is hard to diagnose
The deployment is green and the static app works. The API fails as a platform-level 404, with no Function handler execution. This makes the deployed API look empty even though the deploy action says the API build/upload completed successfully.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.