Skip to content

Parser throws "unexpected token '(' ... valid tokens [)]" on nested parentheses in commit body #54

Description

@benjamineckstein

Summary

parser() throws unexpected token '(' at L:C, valid tokens [)] when a commit
body (or a scope) contains nested parentheses. The body of a conventional
commit is free-form text per the spec, so it should not be rejected for
containing nested (...). This commonly happens when a body quotes code, e.g.
z.array(z.boolean()).

Environment

  • @conventional-commits/parser: 0.4.1 (current npm latest)
  • Node.js: v25.6.1

Minimal reproduction

import { parser } from '@conventional-commits/parser';

// nested parentheses in the body
parser('fix: x\n\ncall(inner(arg))');
// => Error: unexpected token '(' at 3:11, valid tokens [)]

// real-world: a commit body quoting code
parser('fix: x\n\nz.array(z.boolean())');
// => Error: unexpected token '(' at 3:18, valid tokens [)]

Expected vs actual

  • Expected: the message parses; the body is free-form text.
  • Actual: parsing throws on the inner ( because the grammar appears to treat
    (...) in the body as a non-nestable group and expects ) where it finds (.

Characterization

It is specifically nested parens, and position matters (which points at a
grammar issue rather than the input being genuinely invalid):

Input (after fix: x\n\n unless noted) Result
call(arg) — single parens PASS
call(inner(arg)) — nested FAIL 3:11
(()) — empty nested PASS
z.array(z.boolean()) FAIL 3:18
z.array(z.boolean()) done — trailing text FAIL
see z.array(z.boolean()) — leading text PASS
a(1) b(2) — two separate groups PASS
fix: call(inner(arg)) — nested in subject description PASS
fix(a(b)): x — nested in scope FAIL 1:6

Downstream impact

This surfaces through release-please, which depends on this parser. When a
commit that landed on the default branch has a body quoting code with nested
parens (e.g. z.array(z.boolean())), release-please logs
commit could not be parsed ... error message: Error: unexpected token '(' ...,
silently skips that commit, finds zero releasable commits, and opens no
release PR. The fix never ships and there is no failing check to signal it, so
the breakage is easy to miss.

Happy to help with a fix / test case if useful.

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