Skip to content

How to read a rejected commit

The pre-commit hooks block a commit that would break the build or the conventions. The output is long — especially on large commits — and the line that explains the rejection is rarely the last one printed. This guide is about finding it. For what the hooks run and why, see what happens when you commit.

Find the verdict, ignore the collateral

The run always ends with husky's husky - pre-commit script failed (code 1) line and npm's error tail — scroll up from there. A large commit is linted in concurrent chunks, and one failing chunk cancels all others; the cancelled chunks print as noise:

✖ Task killed: node ./scripts/dia-scripts/index.mjs lint metadata
✖ Task killed: node ./scripts/dia-scripts/index.mjs lint metadata

Every Task killed: line is a consequence, not a cause. The block you want names its task with a colon and ends in a verdict:

✖ node ./scripts/dia-scripts/index.mjs lint metadata:

[x] 2 violation(s) introduced by this commit, on lines it changed:
      force-app/main/default/classes/CaseService.cls:42  pmd:ApexCRUDViolation
          Validate CRUD permission before SOQL/DML operation
[i] 8 further pre-existing violation(s) in the same files.

The verdicts and what to do

Verdict block Meaning Fix
[x] N violation(s) introduced by this commit, on lines it changed The lint gate blocks only what your commit introduced. Pre-existing counts ([i] …) are informational. Fix the named lines, or suppress deliberately. Re-commit.
[x] N violation(s) introduced by this commit … naming a regex:Salesforce…, regex:…Token, regex:PrivateKeyBlock or regex:GenericCredentialAssignment rule under lint secrets A credential-shaped value sits on a line you are committing. The value has not left your machine. Follow how to handle a committed secret from step 4; for a placeholder, add the DO-NOT-USE marker.
✖ header must not be longer than 100 characters (and other commitlint rules), then husky - commit-msg script failed (code 1) The message was rejected, not the change. The files stay staged. Commit again with a conventional message (fix: …, feat: …, chore: …) — npm run cm (Commitizen) writes a conforming one; nothing else to redo.
file.md:12 MD013/line-length … markdownlint rejected a staged markdown file. Fix the line (or adjust .markdownlintrc.js deliberately). Re-commit.
Jest output with failing specs The JavaScript step runs the tests related to your staged files. Fix code or test, re-commit.
Build/webpack errors after lint-staged npm run validate runs a build check after the per-file tasks. Fix the build, re-commit.
Error (…) without a violations table The scan itself crashed — not a verdict about your code. Read the error; if it names a missing file or tool, fix the environment and re-commit.

Where the output surfaces

  • Terminal: everything above appears inline. Nothing else to know.
  • VS Code: the Source Control commit button shows only a small error toast; the full hook output is in the Git output channel (the toast's button — "Show Command Output" or "Open Git Log" depending on the version). Committing from the integrated terminal shows it directly.

The state you are left in

Your work is intact either way: staged files stay staged, nothing is half-committed. A failure inside lint-staged also rolls back the formatting it had just applied (you will see Reverting to original state because of errors...); a failure in the later build check or in commit-msg keeps it. The full scan report is readable under logs/ when the verdict has scrolled away. Fix the cause — npm run format:changed and npm run lint re-check without committing — and run the same git commit again.

Do not bypass the hooks with --no-verify — see bypassing the hooks only moves the failure.