can1357/oh-my-pi · error · RangeError
Format string contains an unescaped latin alphabet character
Error message
Format string contains an unescaped latin alphabet character `${character}` What it means
The custom date-fns-v4-compatible formatter throws RangeError when the pattern contains an unescaped latin letter it does not recognize as a supported token. date-fns semantics require unknown letters to be quoted with single quotes so they are literal text.
Source
Thrown at packages/utils/src/dates.ts:138
continue;
}
index++;
break;
}
continue;
}
const rest = pattern.slice(index);
const token = TOKENS.find(candidate => rest.startsWith(candidate));
if (token) {
result += tokenValue(date, token);
index += token.length;
continue;
}
const character = pattern[index++];
if (/[A-Za-z]/.test(character)) {
throw new RangeError(`Format string contains an unescaped latin alphabet character \`${character}\``);
}
result += character;
}
return result;
}
function plural(count: number, singular: string): string {
return `${count} ${count === 1 ? singular : `${singular}s`}`;
}
function completedMonths(earlier: Date, later: Date): number {
let months = (later.getFullYear() - earlier.getFullYear()) * 12 + later.getMonth() - earlier.getMonth();
if (months === 0) return 0;
const candidate = new Date(earlier);
candidate.setDate(1);
candidate.setFullYear(earlier.getFullYear(), earlier.getMonth() + months, 1);View on GitHub (pinned to 9690622007)
Solutions
- Quote literal letters with single quotes: 'yyyy-MM-dd "(UTC)"' becomes "yyyy-MM-dd '(UTC)'" in date-fns style.
- Replace unsupported tokens with supported v4 tokens (see the formatter's token table).
- Wrap whole words in quotes: "yyyy 'at' HH:mm".
- Escape a literal single quote by doubling it inside a quoted section.
Example fix
// before format(d, "yyyy-MM-dd (UTC)"); // RangeError: unescaped `U` // after format(d, "yyyy-MM-dd '(UTC)'");
Defensive patterns
Strategy: validation
Validate before calling
// reject unescaped latin letters outside quoted sections before formatting
if (/(^|')([^']*)[A-Za-z]/.test(pattern.replace(/'[^']*'/g, ""))) {
throw new Error('Pattern contains unescaped letters; quote literals with single quotes');
} Try / catch
try {
return format(date, pattern);
} catch (err) {
if (err instanceof RangeError && err.message.includes('unescaped latin alphabet')) {
console.error(`Bad format string "${pattern}": ${err.message}`);
return '';
}
throw err;
} Prevention
- Wrap literal text (words like 'at', 'UTC') in single quotes inside the pattern.
- Only use tokens documented as supported (date-fns v4 set) when porting from other libraries.
- Keep a small test over each production format string.
When it happens
Trigger: Calling format(date, pattern) with a pattern containing unsupported bare letters, e.g. 'yyyy-MM-dd (UTC)' where 'U','T','C' are unquoted, or patterns using tokens from other libraries (e.g. 'DD', 'hh a' variants) not in the supported set.
Common situations: Porting patterns from Moment.js/Luxon/day.js, embedding words like 'at' or 'UTC' directly in the pattern, or copying date-fns patterns that use tokens this shim does not implement.
Related errors
- Invalid time value
- Unsupported language '{value}'. Supported: {}
- Unable to infer language from file extension: {}. Specify `l
- Invalid pattern: {err}
- Failed to load tree-sitter language: {err}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/2c6301086e65b699.
Report an issue: GitHub.