Skip to content

vite-wv scaffold: lint-staged glob breaks pre-commit on docs/config-only commits (ultracite errors when no JS/TS files staged) #280

@ernestkoe

Description

@ernestkoe

Summary

The scaffolded lint-staged config breaks the husky pre-commit hook for any commit that doesn't touch a .js/.jsx/.ts/.tsx file (e.g. a docs- or config-only commit). ultracite fix exits non-zero with No files found to lint, so husky aborts the commit.

Environment

  • @proofkit/cli@2.2.0-beta.6, init . --app-type webviewer --non-interactive
  • ultracite@^7.7.0 (oxlint + oxfmt), husky@^9.1.7, lint-staged@^17
  • node 24.14.1, pnpm 11.1.3, macOS

What the scaffold produces

package.json:

"lint-staged": {
  "*.{js,jsx,ts,tsx,json,jsonc,css,scss,md,mdx}": [
    "pnpm exec ultracite fix"
  ]
}

The glob spans md/mdx/json/jsonc/css/scss, but ultracite drives oxlint, which only lints the JS/TS family. When lint-staged hands ultracite fix a staged set containing none of those (e.g. only *.md + package.json), it fails:

✖ pnpm exec ultracite fix:
Finished in 132ms on 1 files using 14 threads.
No files found to lint. Please check your paths and ignore patterns.
husky - pre-commit script failed (code 1)

Reproduction

npx @proofkit/cli@beta init . --app-type webviewer --non-interactive
git init -b main && git add -A && git commit -m "init"   # ok (has TS files)
# now a docs-only change:
printf '\n' >> README.md
git add README.md
git commit -m "docs"     # FAILS: ultracite "No files found to lint"

It fails even when the only staged file is package.json — i.e. it's not specific to markdown; it's "no JS/TS files in the staged set."

Root cause

This comes from ultracite's lint-staged integration, wired by the CLI in
packages/cli/src/helpers/ultracite.ts:

const ULTRACITE_INTEGRATIONS = ["husky", "lint-staged"] as const;

The same glob ships in this repo's own root package.json. Two things combine:

  1. The integration writes a glob covering extensions oxlint doesn't lint.
  2. ultracite fix treats "zero matched files after filtering" as an error (exit 1) rather than a no-op.

This likely belongs upstream in proofsh/ultracite (the integration generator), but it surfaces on every scaffolded ProofKit project, so flagging it here.

Impact

  • Every ProofKit webviewer project hits this on routine docs/config commits.
  • The natural workaround users reach for is git commit --no-verify — which also bypasses any other pre-commit hooks (e.g. a gitleaks secret-scan), turning a formatting annoyance into a security footgun.

Suggested fixes (any one)

  1. Scope the lint-staged glob to what oxlint actually lints:
    "*.{js,jsx,ts,tsx}": ["pnpm exec ultracite fix"].
  2. Make ultracite fix exit 0 (no-op) when no matching files remain after filtering.
  3. Add a --no-error-on-unmatched style flag and use it in the lint-staged integration.

Workaround (current)

Narrow the glob in package.json to *.{js,jsx,ts,tsx}. Docs/config-only commits then run no lint task and the hook passes (gitleaks etc. still run).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions