gleam-lang/gleam · error · TypeError
UTF-codepoint pattern matching is not supported
Error message
UTF-codepoint pattern matching is not supported
What it means
Gleam compile error (TypeError::OptionNotSupportedForTarget): when type-checking bit array segments in pattern position that use utf8_codepoint, utf16_codepoint, or utf32_codepoint while compiling for the JavaScript target. The guard mode == TypeOptionsMode::Pattern && target == Target::JavaScript fires because the JS codegen cannot destructure UTF codepoint segments in patterns (it can still construct them in expressions); the compiler rejects the segment with UnsupportedOption::UtfCodepointPattern and points at the offending option.
Source
Thrown at compiler-core/src/bit_array.rs:115
fn type_options<TypedValue>(
input_options: &[BitArrayOption<TypedValue>],
mode: TypeOptionsMode,
must_have_size: bool,
target: Target,
) -> Result<Arc<Type>, Error>
where
TypedValue: GetLiteralValue,
{
use BitArrayOption::*;
let mut categories = SegmentOptionCategories::new();
// Basic category checking
for option in input_options {
match option {
Utf8Codepoint { .. } | Utf16Codepoint { .. } | Utf32Codepoint { .. }
if mode == TypeOptionsMode::Pattern && target == Target::JavaScript =>
{
return err(
ErrorType::OptionNotSupportedForTarget {
target,
option: UnsupportedOption::UtfCodepointPattern,
},
option.location(),
);
}
Bytes { .. }
| Int { .. }
| Float { .. }
| Bits { .. }
| Utf8 { .. }
| Utf16 { .. }
| Utf32 { .. }
| Utf8Codepoint { .. }
| Utf16Codepoint { .. }
| Utf32Codepoint { .. } => {View on GitHub (pinned to 3e3c5ddc08)
Solutions
- Rewrite the pattern without codepoint options: match the remaining bytes (e.g. <<rest:bytes>>) and decode with bit_array.to_string / string functions afterwards
- Match on Gleam String values directly where possible, since Gleam strings are UTF-8 and support pattern matching via case
- Keep such modules on the Erlang target by setting target = "erlang" if JS support is not required
Example fix
// before (panics only at compile time on the JavaScript target)
// gleam.toml: target = "javascript"
pub fn first_codepoint(s: BitArray) {
case s {
<<codepoint:utf8_codepoint, rest:bits>> -> Ok(#(codepoint, rest))
_ -> Error(Nil)
}
}
// after: match bytes, decode as UTF-8 string instead
pub fn first_codepoint(s: BitArray) {
case s {
<<first:bytes-size(1), rest:bits>> ->
case bit_array.to_string(<<first, rest:bits>>) {
Ok(string) -> string_pop_grapheme(string)
Error(Nil) -> Error(Nil)
}
_ -> Error(Nil)
}
} Defensive patterns
Strategy: validation
Validate before calling
# catch target-specific bit array rejections before shipping: check both targets in CI gleam check --target erlang && gleam check --target javascript
Prevention
- Avoid utf8_codepoint/utf16_codepoint/utf32_codepoint in bit array patterns of cross-target code; match bytes or use String matching instead
- Add 'gleam check --target javascript' to CI for projects that also target Erlang
- Remember the restriction is pattern-only and JavaScript-only: construction and the Erlang target remain valid
When it happens
Trigger: Writing a case pattern like '<<c:utf8_codepoint, rest:bits>>' and building/checking with target = "javascript" in gleam.toml or --target javascript. The same pattern compiles fine on the Erlang target.
Common situations: Porting string/binary parsing code originally written for the Erlang target to JavaScript; sharing parsing modules between targets; following Erlang-style binary-matching idioms.
Related errors
- This is an extra type specifier
- Error setting Ctrl-C handler
- Error setting Ctrl-C handler
- Failed to determine user cache directory
- Non Utf8 Path
AI-assisted analysis of gleam-lang/gleam@3e3c5ddc08 (2026-08-20).
Data as JSON: /api/errors/03ecdf7a03ef1688.
Report an issue: GitHub.