toon-format/toon · error · SyntaxError

Missing field name before nested field group

Error message

Missing field name before nested field group

What it means

Inside a field list entry, a nested field group `{...}` was found (e.g. `{a,{b}}` without a name), but the text before the opening brace was empty after trimming. TOON nested field syntax requires a field name before the group, like `user{name,age}`, so nameless groups are rejected.

Source

Thrown at packages/toon/src/decode/parser.ts:234

 * after a nested group's closing brace; callers decide strict fallthrough.
 */
export function parseFieldEntries(fieldsContent: string, delimiter: Delimiter): FieldNode[] {
  const entries = splitFieldEntries(fieldsContent, delimiter)

  return entries.map((entry) => {
    const trimmedEntry = trimSpaces(entry)
    if (!trimmedEntry) {
      throw new SyntaxError('Empty field name in field list')
    }

    const groupStart = findUnquotedChar(trimmedEntry, OPEN_BRACE)
    if (groupStart === -1) {
      return { name: parseStringLiteral(trimmedEntry) }
    }

    const namePart = trimSpaces(trimmedEntry.slice(0, groupStart))
    if (!namePart) {
      throw new SyntaxError('Missing field name before nested field group')
    }

    const groupEnd = findMatchingBrace(trimmedEntry, groupStart)
    if (groupEnd === -1) {
      throw new SyntaxError('Unmatched brace in field list')
    }
    if (groupEnd !== trimmedEntry.length - 1) {
      throw new SyntaxError('Unexpected content after nested field group')
    }

    const children = parseFieldEntries(trimmedEntry.slice(groupStart + 1, groupEnd), delimiter)
    return { name: parseStringLiteral(namePart), children }
  })
}

/**
 * Splits a field list on the active delimiter at brace depth zero,
 * respecting quoted names and escape sequences.

View on GitHub (pinned to 604eac266e)

Solutions

  1. Add the missing field name before the brace group, e.g. `user{name}` instead of `{name}`
  2. If the source object has an unnamed key, rename it before encoding
  3. Check every `{` in the field list has a non-empty name immediately before it
  4. Fix the generator to emit `name{...}` for every nested group

Example fix

// before
users[2]{{name},age}:
// after
users[2]{user{name},age}:
Defensive patterns

Strategy: try-catch

Validate before calling

function hasUnnamedNestedGroups(toonText) {
  const m = toonText.match(/\[\d+\]\{([^}]*)\}/)
  if (!m) return false
  return /[{,;\t]\s*\{/.test(`{${m[1]}}`) // brace group not preceded by a name
}

Try / catch

try {
  const value = toon.decode(text)
} catch (err) {
  if (err instanceof SyntaxError && err.message === 'Missing field name before nested field group') {
    // prompt to add the missing parent field name
  } else throw err
}

Prevention

When it happens

Trigger: Decoding a header field list containing a bare nested group with no preceding name — e.g. `items[2]{{name},age}:` or an entry like `,` followed by `{...}` — via parseFieldEntries when parsing parseArrayHeaderLine.

Common situations: Hand-writing nested TOON headers and forgetting the parent field name; generators that omit a name for nested object columns (e.g. unnamed object fields in source JSON); copy-paste errors deleting a name but leaving its group.

Related errors


AI-assisted analysis of toon-format/toon@604eac266e (2026-08-31). Data as JSON: /api/errors/aa5bea1c131fea82. Report an issue: GitHub.