helix-editor/helix · error · anyhow::Error
could not interpret '{}' as a Unicode character code
Error message
could not interpret '{}' as a Unicode character code What it means
A Unicode expansion token (%u{...}, e.g. %u{25CF}) is expanded by parsing its content as hexadecimal with u32::from_str_radix(_, 16) and then char::from_u32. The error fires when the content is not valid hex or is a number that is not a valid Unicode scalar value (above 0x10FFFF, or in the surrogate range D800-DFFF).
Source
Thrown at helix-view/src/expansion.rs:123
/// `Editor`. See `expand_variable` below for more discussion of lifetimes.
pub fn expand<'a>(editor: &Editor, token: Token<'a>) -> Result<Cow<'a, str>> {
// Note: see the `TokenKind` documentation for more details on how each branch should expand.
match token.kind {
TokenKind::Unquoted | TokenKind::Quoted(_) => Ok(token.content),
TokenKind::Expansion(ExpansionKind::Variable) => {
let var = Variable::from_name(&token.content)
.ok_or_else(|| anyhow!("unknown variable '{}'", token.content))?;
expand_variable(editor, var)
}
TokenKind::Expansion(ExpansionKind::Unicode) => {
if let Some(ch) = u32::from_str_radix(token.content.as_ref(), 16)
.ok()
.and_then(char::from_u32)
{
Ok(Cow::Owned(ch.to_string()))
} else {
Err(anyhow!(
"could not interpret '{}' as a Unicode character code",
token.content
))
}
}
TokenKind::Expand => expand_inner(editor, token.content),
TokenKind::Expansion(ExpansionKind::Shell) => expand_shell(editor, token.content),
TokenKind::Expansion(ExpansionKind::Register) => expand_register(editor, token.content),
// Note: see the docs for this variant.
TokenKind::ExpansionKind => unreachable!(
"expansion name tokens cannot be emitted when command line validation is enabled"
),
}
}
/// Expand a shell command.
pub fn expand_shell<'a>(editor: &Editor, content: Cow<'a, str>) -> Result<Cow<'a, str>> {
use std::process::{Command, Stdio};View on GitHub (pinned to 079a789e8c)
Solutions
- Use 1-6 hexadecimal digits without prefix: %u{25CF}, %u{1F600}.
- Keep the value within 0..=0x10FFFF and outside D800-DFFF.
- If you literally want text like "%u{...}" in output, escape the percent as %%u{...}.
Example fix
# before
:echo %u{U+25CF}
# after
:echo %u{25CF} Defensive patterns
Strategy: validation
Validate before calling
fn valid_unicode_expansion(hex: &str) -> bool {
u32::from_str_radix(hex, 16).ok().and_then(char::from_u32).is_some()
}
if !valid_unicode_expansion(content) {
return Err(anyhow!("'{content}' is not a hex Unicode scalar (max 10FFFF, no surrogates)"));
} Type guard
fn parse_codepoint(hex: &str) -> Option<char> {
u32::from_str_radix(hex, 16).ok().and_then(char::from_u32)
} Try / catch
match u32::from_str_radix(hex, 16).ok().and_then(char::from_u32) {
Some(ch) => out.push(ch),
None => return Err(anyhow!("invalid Unicode codepoint '{hex}'")),
} Prevention
- Strip U+ prefixes, spaces, and '#x' style prefixes before submitting codepoints.
- Reject values above 0x10FFFF and the D800-DFFF surrogate range up front.
- Escape a literal % as %% when the digits are meant as text.
When it happens
Trigger: Writing %u{zzzz} (non-hex digits), %u{110000} (beyond the scalar range), or %u{D800} (unpaired surrogate); accidentally including the U+ prefix or spaces, e.g. %u{U+25CF}.
Common situations: Copy-pasting codepoints formatted as U+25CF from unicode.org or char maps; miscounting digits; assuming surrogate halves are addressable like in UTF-16.
Related errors
- unknown variable '{}'
- {err}
- Failed to parse snippet. Remaining input: {}
- Command not provided
- Incorrect transport {}
AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16).
Data as JSON: /api/errors/59278e3aa1939a17.
Report an issue: GitHub.