Azure Static Web Apps: Fixing the "App Content Too Large" Deployment Error
This document describes the root cause, diagnosis, and fix for the Azure Static Web Apps (SWA) deployment failure on rksp-vtk-react when publishing to the Free tier.
Symptom
During the Build And Deploy step in GitHub Actions, deployment failed with:
The content server has rejected the request with: BadRequest
Reason: The size of the app content was too large. The limit for this Static Web App is 262144000 bytes.
262,144,000 bytes = 250 MB, which is the app content size limit on the Azure SWA Free plan.
Initial Assumption (Incorrect)
Because this is a large application (VTK.js, ITK-wasm, CopilotKit, 22,000+ Vite modules), we initially suspected the built dist/ folder was too large and needed trimming or a plan upgrade.
Local investigation showed that was not the problem.
Actual Root Cause
The deployment was uploading far more than the built app.
| Content | Approximate size |
|---|---|
dist/ (production build output) | ~25 MB |
node_modules/ | ~629 MB |
Full repo (source + node_modules) | ~665 MB |
The built app was well under the 250 MB limit. Azure rejected the upload because the workflow was configured to deploy from the repository root instead of dist/ only, so node_modules and other source files were included in the upload payload.
Why the workflow misconfiguration happened
We build in GitHub Actions and skip Azure's Oryx build with skip_app_build: true. That requires a specific SWA workflow configuration documented by Microsoft. Our workflow used an incorrect combination:
# INCORRECT — uploads from repo root, includes node_modules
app_location: "/"
output_location: "dist"
skip_app_build: true
app_artifact_location: "dist"
With app_location: "/" and skip_app_build: true, the deploy action treated the repo root as the app content folder. Setting output_location: "dist" does not restrict the upload to dist/ in this mode. The app_artifact_location input is an alias for output_location and did not correct the behavior when app_location pointed at /.
Reference: Azure Static Web Apps build configuration — Skip building front-end app
The Fix
1. Correct SWA deploy configuration (primary fix)
When building in a prior GitHub Actions step, configure the deploy step as follows:
- name: Build app
run: node .yarn/releases/yarn-4.13.0.cjs build
- name: Report build artifact size
run: |
echo "Deploy artifact summary:"
du -sh dist
find dist -type f | wc -l
- name: Remove node_modules before deploy
run: rm -rf node_modules
- name: Build And Deploy
uses: Azure/static-web-apps-deploy@v1
with:
action: "upload"
app_location: "dist" # Deploy ONLY the build output
output_location: "" # Required when skip_app_build is true
skip_app_build: true
api_location: ""
# ... tokens and other settings
Key rules when using skip_app_build: true:
| Setting | Value | Purpose |
|---|---|---|
app_location | "dist" | Points at the pre-built static files |
output_location | "" (empty string) | Required by Azure when skipping Oryx build |
skip_app_build | true | Tells Azure not to run its own build |
Do not set app_location: "/" when pre-building in CI.
2. Remove node_modules before deploy (safety net)
Even with the correct app_location, deleting node_modules before the deploy step prevents accidental inclusion if configuration changes in the future:
- name: Remove node_modules before deploy
run: rm -rf node_modules
3. Add a deploy artifact size check (observability)
A reporting step makes future size issues easy to spot in CI logs:
- name: Report build artifact size
run: |
echo "Deploy artifact summary:"
du -sh dist
find dist -type f | wc -l
Expected output after a successful build:
Deploy artifact summary:
25M dist
519
If this step ever shows hundreds of MB or thousands of files, something is wrong with the build or deploy configuration.
Related Changes (Supporting, Not the Size Fix)
These changes were made during the same deployment troubleshooting effort. They solved other CI issues or improved performance but were not required to fix the 250 MB limit error.
Pre-build in GitHub Actions instead of Azure Oryx
The app is too heavy for Azure's default Oryx build environment (memory limits, Yarn version mismatch). We build in GitHub Actions and upload the result:
- Install dependencies with Yarn 4 (
node .yarn/releases/yarn-4.13.0.cjs install --immutable) - Build with increased Node heap (
NODE_OPTIONS: --max-old-space-size=8192+ swap space on the runner) - Deploy only
dist/
JavaScript heap out of memory during build
GitHub-hosted runners have ~7 GB RAM. Our Vite build needs more for 22,000+ modules. Mitigations:
NODE_OPTIONS: --max-old-space-size=8192at the job level- 10 GB swap added before install/build
maxParallelFileOps: 1invite.config.mjsto reduce Rollup peak memory
Yarn 4 in CI
The project uses Yarn 4.13.0 (packageManager field + Berry lockfile). CI invokes the committed binary directly to avoid the runner's global Yarn 1.22.x:
run: node .yarn/releases/yarn-4.13.0.cjs install --immutable
run: node .yarn/releases/yarn-4.13.0.cjs build
CopilotKit lazy loading (runtime optimization)
CopilotKit (including shiki syntax highlighting and mermaid) was moved out of the main entry bundle and lazy-loaded from the dashboard layout only:
- New component:
src/components/CopilotAppShell.jsx - Removed
CopilotKitfromsrc/index.jsx - Dashboard layout lazy-loads
CopilotAppShellandAiAssistantDialog
This improves initial page load (login no longer downloads the Copilot stack) but does not materially change total deploy size—all chunks still ship in dist/.
What's Actually in dist/ (~25 MB)
For reference, a typical production build contains:
| Category | Approx. size | Notes |
|---|---|---|
| JavaScript bundles | ~19 MB | VTK, CopilotKit/shiki, MUI, app code |
| Static images | ~4 MB | Logos, template mock images in public/static/ |
| Fonts (KaTeX, etc.) | ~1 MB | Pulled in by CopilotKit markdown rendering |
| CSS, HTML, misc | <1 MB |
The largest single chunk is the CopilotKit-related bundle (~4–6 MB minified). Even with all chunks included, total deploy size is roughly 10× smaller than the Free tier limit.
Verification Checklist
After applying the fix, confirm in GitHub Actions:
- Build completes without OOM errors.
- Report build artifact size shows ~25 MB and ~500 files (not hundreds of MB or 10,000+ files).
- Build And Deploy succeeds without the BadRequest size error.
- The deployed site loads correctly at the SWA URL.
Locally, you can sanity-check before pushing:
yarn build
Get-ChildItem dist -Recurse -File | Measure-Object -Property Length -Sum
Expected total: ~25–30 MB.
Do We Need the Standard Plan?
No, for this specific error. The Free tier 250 MB limit is sufficient when only dist/ is deployed.
Consider upgrading to Standard only if:
- The actual
dist/output genuinely grows beyond 250 MB, or - You need other Standard-tier features (custom domains, SLA, higher limits, etc.)
Troubleshooting Guide
Error returns after a workflow edit
Check that app_location is still "dist" and output_location is still "". A revert to app_location: "/" will bring the error back.
du -sh dist shows >250 MB in CI
The build output itself is too large. Investigate:
- Accidental inclusion of large assets in
public/ - Source maps enabled in production (
build.sourcemap: truein Vite) - Unintended files copied into
dist/
Deploy succeeds but site is broken
Ensure public/_redirects, staticwebapp.config.json (if used), and SPA routing assets are present in dist/. Vite copies public/ contents into dist/ during build.
File count limit error (15,000 files)
A separate SWA limit. If encountered, check that node_modules is not being uploaded. Same root cause as the size error.
Summary
| Problem | Root cause | Fix |
|---|---|---|
| "App content too large" (250 MB) | Deploy uploaded repo root + node_modules (~665 MB), not dist/ (~25 MB) | Set app_location: "dist", output_location: "", skip_app_build: true; remove node_modules before deploy |
The application was never too large for Azure SWA Free—the deployment package was pointed at the wrong folder.
References
- Azure Static Web Apps — Build configuration
- Azure Static Web Apps — FAQ (size limits)
- Azure/static-web-apps-deploy GitHub Action
- Workflow file:
.github/workflows/azure-static-web-apps-red-field-0d0aada10.yml