Repository navigation
Update issue template - #392
Merged
Merged
Conversation
prompt the user regarding netlify --info
sarahetter
pushed a commit
that referenced
this pull request
Oct 6, 2026
…tly (#8572) Opened by Netliloop run [#392](https://netliloop.netlify.app/#/runs/392) (security-scan), asked in [Slack](https://slack.com/archives/C095D1JL480/p1791299459766719?thread_ts=1791298825.895999&cid=C095D1JL480) ### Why - Renovate's [#8472](#8472) (`content-type` v1 → v3) fails every build job: v3 is ESM-only, has no default export, and `parse()` takes a header string instead of a request object, so `src/utils/proxy.ts` and `src/lib/functions/form-submissions-handler.ts` no longer compile. Its sibling [#8377](#8377) (`@types/content-type` v2) fails lint on its own because v2 is a stub pointing at the package's bundled types. - Both PRs have re-run and failed on every weekly rebase since July; together they account for 64 + 40 failed integration jobs in the last four weeks. ### What changed - `content-type` goes to `^3.1.1` and `@types/content-type` is removed (v3 ships its own types). - The three call sites import `parse` by name and pass `req.headers['content-type']`. The proxy already guarded on the header being present; the form handler now defaults a missing header to `''`, which parses to an empty type and falls through to neither form branch, matching the proxy's guard. - Behaviour change to know about: v3 `parse()` never throws on a string, where v1 threw `TypeError` on a missing or malformed header. In `src/utils/proxy.ts` that TypeError was an unhandled rejection that crashed `netlify dev` on any POST with a malformed `Content-Type`; now such a request proxies normally and gets the static server's 405 (the new test covers this). The proxy only forwards form content types to the form handler, so the handler's own `?? ''` is reached only when the functions server is called directly; there a missing header now takes the existing `Invalid Content-Type` warn-and-continue branch instead of throwing. - A `charset` parameter is passed through to `raw-body` exactly as before: v1 also accepted any token value there, so `charset=bogus` still ends in `raw-body`'s 415. - All three call sites use the same `req.headers['content-type'] ?? ''` idiom. - Root `node_modules/content-type` is now the ESM-only v3; `npm ls content-type` shows `express`, `body-parser`, `type-is` and verdaccio each keep a nested v1/v2 copy, so no CommonJS `require('content-type')` resolves to v3. - Supersedes #8472 and #8377, which can be closed when this merges. ### How we verified - `npm run build`, `npm run typecheck`, `npm run lint`: all exit 0 (on #8472 the build fails with TS1192 and TS2345). - `CI=true npm run test:unit`: 80 files passed. - New integration test `should keep serving when a form submission carries a malformed content type`: a POST with `Content-Type: not/a valid; ;;` and a POST with no `Content-Type` at all (sent as a Buffer body, since node-fetch adds `text/plain` to a string body) must each get a 405 and the next GET a 200. On `main` it fails with `request to http://localhost:33773/ failed, reason: socket hang up` because the unhandled TypeError from `content-type@1` kills the dev server; on this branch it passes (5.5 s). - `CI=true npx vitest run --retry=3 tests/integration/commands/dev/dev-forms-and-redirects.test.ts` with the new test included: 14 passed (14). - End to end with the built CLI (`node bin/run.js dev --offline`) against a fixture with a `submission-created` function, [commands and output here](https://netliloop.netlify.app/api/files/eyJrZXkiOiJldmlkZW5jZS8zOTIvZWZjYTE0YzgtYTFiMy00MzFjLWJmNjUtNzkzODA2ZGRlOTFiIiwibmFtZSI6ImNvbnRlbnQtdHlwZS12My1kZXYtZm9ybS1yZWNlaXB0cy50eHQiLCJ0eXBlIjoidGV4dC9wbGFpbiIsImV4cCI6MTgyMjgzNjk3OTIwNX0.f3ULpDp40grpAemeOoh55S3xXaZNBT5HVHJOjsr7JuE): a urlencoded POST and a multipart POST with a file attachment both reached the function with the parsed fields (200, function log shows the fields); POSTs with no `Content-Type`, a malformed one, and `application/json` were not treated as forms (405) and a GET afterwards returned 200; `application/x-www-form-urlencoded; charset=UTF-8` still matched. ### What is left to test - Nothing. CI ran the full matrix on the final commit: 35 checks, all green (unit on ubuntu/macOS/Windows, 8 integration shards, e2e, lint, format, typecheck, verify-docs, package-size). ### Risk `low`: one narrow code path in `netlify dev` (form-submission routing), covered by the integration test and the end-to-end check above; a wrong result shows immediately as a form POST not reaching the handler. No Linear issue: a self-contained dependency fix the CLI team can merge from this description. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Netliloop <netliloop@netlify.com>
sarahetter
added a commit
that referenced
this pull request
Oct 6, 2026
Opened by Netliloop run [#392](https://netliloop.netlify.app/#/runs/392) (security-scan), asked in [Slack](https://slack.com/archives/C095D1JL480/p1791299459766719?thread_ts=1791298825.895999&cid=C095D1JL480) ### Why - `vitest@3.2.7` carries [GHSA-82fw-gwwq-j7x9](GHSA-82fw-gwwq-j7x9) (`@vitest/mocker` path traversal, patched in 4.1.11). Renovate's [#8289](#8289) and [#8320](#8320) target it but their lockfiles no longer resolve against `main` (`npm ci` fails on every rebase), and Dependabot's [#8570](#8570) jumps to vitest 5 and fails typecheck, lint and 12 unit tests. - `oxfmt@0.61.0` pins `tinypool@2.1.0`, which carries the critical [GHSA-85c8-ppgw-ccpr](GHSA-85c8-ppgw-ccpr); the only way past it is an oxfmt version that pins `tinypool >= 2.1.2`. - `npm audit` on `main` lists `vitest`, `@vitest/mocker`, `@vitest/coverage-v8` and `tinypool`; on this branch none of them appear. ### What changed - `vitest` and `@vitest/coverage-v8` go to `^4.1.11`, the first patched release (vitest 5 is a week old). - `oxfmt` goes to `0.72.0`, which pins `tinypool@2.2.0`; running it reformats two files under `src/commands/logs/sources/`. - vitest 4 removed `poolOptions`, so `threads.singleThread: true` becomes `maxWorkers: 1` in both configs: still one worker thread, one file at a time. This is not a byte-for-byte port. The migration guide's equivalent adds `isolate: false`, but in vitest 4 that shares module mocks across files and fails 38 unit tests here, so file isolation stays on and the comment in each config says why. Each file now gets a fresh worker; the Windows-hang TODO beside the pin still applies and CI's Windows jobs on this PR are the check. - Transitively, vitest now carries its own nested Vite 8.3.3 (rolldown) instead of the top-level Vite 7.3.5, so test-file transforms change engine. - Coverage reports change shape (vitest 4 drops `coverage.all` and uses AST remapping), so the Codecov numbers on this PR will move; that is the tooling, not a regression. - vitest 4 constructs mocks called with `new`, so the `NetlifyAPI` and `LocalState` mock implementations in three test files become `function` expressions instead of arrow functions. - `toThrowError` is marked `@deprecated` ("Alias for `expect.toThrow`") in `@vitest/expect` 4 and so flagged by `@typescript-eslint/no-deprecated`; 38 call sites in `tests/` switch to `toThrow` with the same arguments. - Supersedes #8289, #8320 and #8570, which can be closed when this merges. ### How we verified - `npm ci --dry-run`: the committed lockfile is in sync with `package.json` (Renovate's #8289 and #8320 fail exactly here). - `npm run build`, `npm run typecheck`, `npm run lint`, `npm run format:check`: all exit 0. - `CI=true npm run test:unit -- --coverage`: 80 files, 667 tests passed, the same counts as `CI=true npm run test:unit` on `main`. With the migration guide's `isolate: false` the same command fails 38 tests in 9 files (leaked module mocks), which is why isolation stays on. - `CI=true npx vitest run --retry=3 --coverage tests/integration/commands/env/env.test.ts tests/integration/commands/dev/dev-forms-and-redirects.test.ts`: 2 files, 32 tests passed, so `--retry`, `--coverage` and the integration harness work on vitest 4 - `CI=true npm run test:integration -- --shard=1/4` here: 24 failures in 6 files, and the same 6 files fail with the same 24 tests on `main` under vitest 3 (this machine has a linked Netlify site and no git identity, which `build`, `clone` and `link` tests depend on); the full set is CI's 8 green shards. - `npx vitest list --config vitest.e2e.config.ts`: the e2e config loads and lists 5 tests. - `CI=true npx vitest run --config vitest.e2e.config.ts -t "npm →"` runs through verdaccio publish, `npm install`, `netlify --help` and `netlify link` on vitest 4 and fails at the `netlify unlink` assertion (`expected ... to contain 'Run netlify link to link it'`). The identical run on `main` with vitest 3 fails at the same line: this machine has a globally linked Netlify site (`main` received `Unlinked from netliloop`) and, once unlinked, the CLI running under `npx` phrases the hint as `Run npx netlify link` (the branch received that). The failure is the environment, not the upgrade; the e2e suite is unverified here. - `npm audit --json`: on `main` it lists `vitest` (critical, range 0.0.95 - 4.1.10), `@vitest/mocker`, `@vitest/coverage-v8` and `tinypool <=2.1.1`; on this branch none of the four appear and `npm ls tinypool` shows only `oxfmt@0.72.0 → tinypool@2.2.0`. 39 advisories remain, unchanged from `main`; the two critical ones are `proxy-addr` (Dependabot's #8567 fixes it) and `shell-quote`. ### What is left to test - The full integration suite, the e2e suite, and unit/integration on macOS and Windows (where the single-thread pin matters most) could not run here; on this PR CI ran them and all 34 checks are green (unit on ubuntu/macOS/Windows, 8 integration shards, e2e, lint, format, typecheck, verify-docs, package-size). ### Risk `low`: development tooling only; nothing in `dist/` or the published package changes except the two reformatted files, whose formatting-only diff is in the branch. No Linear issue: a self-contained dependency fix the CLI team can merge from this description. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Netliloop <netliloop@netlify.com> Co-authored-by: Sarah Etter <sarah.etter@netlify.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
- Summary
related - #382
prompts the user regarding netlify --info
- Test plan
N/A
- Description for the changelog
update issue-template prompting the user to paste the results as shown up by
netlify --info