Skip to content

fastify start is broken in 8.0.1: pkgUp is not a function, and CI has been running zero tests since glob 13 #915

Description

@fey

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure it has not already been reported

fastify-cli@8.0.1 (published 2026-09-07) cannot start any server. fastify start throws before it reads the plugin file:

TypeError: pkgUp is not a function
    at getPackageType (/usr/lib/node_modules/fastify-cli/util.js:74:32)
    at requireServerPluginFromPath (/usr/lib/node_modules/fastify-cli/util.js:93:29)
    at runFastify (/usr/lib/node_modules/fastify-cli/start.js:118:34)

I realise #914 and #913 are already open and both carry the fix. Filing this anyway because there is no issue tracking the released breakage, and the impact is wide enough that the patch release may be worth prioritising over the rest of those PRs.

Steps to reproduce

// plugin.mjs
export default async function plugin (app, opts) {
  app.get('/', () => ({ ok: true }))
}
npx fastify-cli@8.0.1 start -a 127.0.0.1 -p 3999 plugin.mjs
curl http://127.0.0.1:3999/

Expected: {"ok":true}. Actual: the process exits with the TypeError above and nothing listens on the port.

Run against main and against fix/restore-test-suite in the same tree, replacing only util.js:

main:                    HTTP 000   TypeError: pkgUp is not a function
fix/restore-test-suite:  HTTP 200   {"ok":true}

Cause

pkg-up was bumped ^3.1.0 -> ^5.0.0 in #679. That is not just a CJS/ESM change, the export shape changed too:

// pkg-up@3.1.0
module.exports = async ({cwd} = {}) => findUp('package.json', {cwd})

// pkg-up@5.0.0
export async function pkgUp({cwd} = {}) { return findUp('package.json', {cwd}) }
export function pkgUpSync({cwd} = {}) { return findUpSync('package.json', {cwd}) }

util.js still does const pkgUp = require('pkg-up'), so under require(esm) it binds the namespace { pkgUp, pkgUpSync } and the call fails. There is no default export to fall back to, require('pkg-up').default is undefined. const { pkgUp } = require('pkg-up'), which both open PRs use, is the right shape.

Why CI did not catch it

suite-runner.js on main uses glob's callback form, removed in glob v9:

glob(pattern, (err, matches) => { /* run() lives in here */ })

With glob@13 the call returns a promise and the callback never fires, so run() is never reached, no test file executes, and the script still exits 0:

const { glob } = require('glob')
let called = false
glob('**/*.json', () => { called = true })
setTimeout(() => console.log('callback fired:', called), 500)
// returned: Promise
// callback fired: false

So every suite has been reporting green on an empty set since glob went 11 -> 13 (#852, Dec 2025), which is how a fastify start-breaking change reached a release. The matches.length === 0 guard in #914 is the part that stops this recurring, and it seems worth having even if the rest of that PR needs more rounds.

Ask

A patch release with just the util.js one-liner would unblock everyone using fastify start from a global install, independently of how long #913/#914 take to land in full.

Environment

  • fastify-cli: 8.0.1
  • node: v26.7.0 and v26.8.1, same result
  • os: Linux (Ubuntu 24.04, container) and the same on the host

Disclosure, since it affects how much you should trust the above: I am a human and I am filing this myself, but the investigation and the wording were done with Claude Code and I have not checked every line of it by hand. Everything above ships with the command that produced it, so please read the numbers as reproducible claims rather than as my personal verification. I am deliberately not opening a pull request, #914 already has the same fix and a duplicate from me would only add noise.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions