.funcignore pattern src/ also empties node_modules/*/src
With respect-funcignore: true, Azure/functions-action matches every path in the package against .funcignore using gitignore semantics. A folder pattern whose only slash is the trailing one — src/, test/ — matches at any depth, so it also empties node_modules/debug/src and similar folders. The dependency can't load, the worker registers no functions, and the function routes answer 404 while the deployment reports success. Write root patterns as /src/, /test/, /infra/.
S respect-funcignore: true porovnává Azure/functions-action každou cestu balíčku s .funcignore podle pravidel .gitignore. Vzor složky, jehož jediné lomítko je to koncové – src/, test/ – platí v jakékoli hloubce, takže vyprázdní i node_modules/debug/src a podobné složky. Závislost se nenačte, worker nezaregistruje žádnou funkci a trasy funkcí vracejí 404, přestože nasazení hlásí úspěch. Vzory pro kořen pište jako /src/, /test/, /infra/.
Symptom
- The deploy step succeeds and the app's root URL still answers 200.
- A function route (in our case the health check) returns 404, and ARM returns an empty function list for the slot.
- The deployed
wwwrootstill listssrc,testorinfra— so it looks as if.funcignorewasn't applied at all. - The host log has the real reason:
[Error] Error: Worker was unable to load entry point "dist/functions/routes.js": Cannot find module 'C:\home\site\wwwroot\node_modules\debug\src\index.js'. Please verify that the package.json has a valid "main" entry
[Warning] No job functions found. …
Cause
When package points to a folder and respect-funcignore is on, the action globs every entry in that folder, makes each path relative to the package root and deletes it when the ignore library says it's ignored — the same rules as .gitignore:
src/has no slash at the start or in the middle, so it matches asrcdirectory at any level — includingnode_modules/debug/src, sonode_modules/debug/src/index.jsgoes too.- The glob returns directory entries without a trailing slash, and a pattern ending in
/only matches directories, soignoredoesn't match the folder entry itself. The folders stay behind, emptied of the matched files — which is why the deployed root still listssrc,testandinfra.
Measured with ignore 5.1.9 and 7.0.5 (the version functions-action v1 ships), same result:
| Path | src/, test/ |
/src/, /test/ |
|---|---|---|
src/app.ts |
removed | removed |
node_modules/debug/src/index.js |
removed | kept |
node_modules/foo/test/x.js |
removed | kept |
dist/functions/routes.js |
kept | kept |
Fix
Anchor every pattern to the package root:
/.git*
/.vscode/
/local.settings.json
/src/
/test/
/infra/
/tsconfig.json
/README.md
Keep the rule from coming back with a tiny test in the repository: read .funcignore and fail on any rule that doesn't start with /. An unanchored file pattern such as README.md or tsconfig.json removes the same files from every package in node_modules too — usually harmless, but it's the same trap.
Notes
- When a deployment "succeeds" but no functions appear, read the host log first. With the default
fileLoggingMode: debugOnlythe host writes log files only while you're debugging in the Azure portal. Turn onalwaysonly temporarily — the documentation warns it hurts cold start and throughput — either inhost.json("logging": { "fileLoggingMode": "always" }) or, without a redeploy, through the app settingAzureFunctionsJobHost__logging__fileLoggingMode=always. Or read the traces in Application Insights. az functionapp function listhas no--slotoption; for a deployment slot call ARM directly:GET …/providers/Microsoft.Web/sites/<app>/slots/<slot>/functions?api-version=2023-12-01.- Sources: functions-action
.funcignorehandling · gitignore pattern format · host.jsonfileLoggingMode.