toon-format/toon · error · TypeError

Invalid delimiter ${JSON.stringify(delimiter)}. Valid delimi

Error message

Invalid delimiter ${JSON.stringify(delimiter)}. Valid delimiters are: comma (,), tab (\t), pipe (|)

What it means

assertValidDelimiter narrows a delimiter option to one of the three supported Delimiter values: comma, tab, or pipe. Any other string — including multi-character, empty, or numeric-like values — throws this TypeError with the offending value JSON-stringified.

Source

Thrown at packages/toon/src/shared/validation.ts:10

import type { Delimiter } from '../types.ts'
import { COMMENT_MARKER, DEFAULT_DELIMITER, DELIMITERS, LIST_ITEM_MARKER } from '../constants.ts'
import { isBooleanOrNullLiteral } from './literal-utils.ts'

const NUMERIC_LIKE_PATTERN = /^[+-]?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i

/** Narrows an arbitrary delimiter option, shared by the library and the CLI so both report it alike. */
export function assertValidDelimiter(delimiter: string): asserts delimiter is Delimiter {
  if (!(Object.values(DELIMITERS) as string[]).includes(delimiter)) {
    throw new TypeError(`Invalid delimiter ${JSON.stringify(delimiter)}. Valid delimiters are: comma (,), tab (\\t), pipe (|)`)
  }
}

/**
 * Checks if a key can be used without quotes.
 *
 * @remarks
 * Valid unquoted keys must start with a letter or underscore,
 * followed by letters, digits, underscores, or dots.
 */
export function isValidUnquotedKey(key: string): boolean {
  return /^[A-Z_][\w.]*$/i.test(key)
}

/**
 * Determines if a string value can be safely encoded without quotes.
 *
 * @remarks

View on GitHub (pinned to 604eac266e)

Solutions

  1. Use one of the supported delimiters: ",", "\t", or "|" (or the Delimiters constants)
  2. Check the option value for stray whitespace or wrong characters coming from config/env
  3. If another separator is required, transform data after encoding/decoding with standard tools

Example fix

// before
const opts = { delimiter: ";" }
// after
const opts = { delimiter: "," } // or "\t" or "|"
Defensive patterns

Strategy: type-guard

Validate before calling

const DELIMITERS = [',', '\t', '|'] as const
type Delimiter = typeof DELIMITERS[number]
function isValidDelimiter(d: unknown): d is Delimiter {
  return typeof d === 'string' && (DELIMITERS as readonly string[]).includes(d)
}

Type guard

function isDelimiter(d: unknown): d is ',' | '\t' | '|' {
  return d === ',' || d === '\t' || d === '|'
}

Try / catch

try {
  const out = encode(data, { delimiter: opts.delimiter })
} catch (e) {
  if (e instanceof TypeError && e.message.startsWith('Invalid delimiter')) {
    // fall back to default comma delimiter
  }
  throw e
}

Prevention

When it happens

Trigger: Calling encode/decode (or resolveOptions) with `delimiter: ";"`, `delimiter: ""`, `delimiter: "::"`, or passing a non-delimiter char via CLI --delimiter flag.

Common situations: Assuming arbitrary delimiters are supported; copying options from another serialization library; CLI scripts templating a delimiter from config that holds ";" or "| " with whitespace.

Understand the failure class

Background: Invalid option value errors: "must be one of", "is not a valid", and "only allows" failures explained — this error's family across 23 libraries.


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