gleam-lang/gleam · error
record updates should not reach code generation
Error message
record updates should not reach code generation
What it means
The JavaScript code generator does not implement `Constant::RecordUpdate`: record update syntax is not representable as a compile-time constant. This panic is a guard asserting such constants were eliminated or rejected in earlier compiler phases.
Solutions
- Rewrite the constant to not use record-update syntax (construct the record fully inside the constant).
- Move the record update out of constant position into a function body, where it is supported.
- If this occurs with valid-looking code, report it as a Gleam compiler bug.
Example fix
// before pub const config = Config(..base, retries: 3) // after pub const config = Config(host: base.host, retries: 3)
Defensive patterns
Strategy: validation
Validate before calling
// reject record updates in constant position before codegen
if let Constant::RecordUpdate { location, .. } = constant {
return Err(error_unsupported_in_constant(location));
} Type guard
fn is_codegen_constant(c: &Constant) -> bool {
!matches!(c, Constant::RecordUpdate { .. } | Constant::Todo { .. } | Constant::Invalid { .. })
} Try / catch
match std::panic::catch_unwind(|| codegen_constant(&c)) {
Ok(doc) => doc,
Err(_) => emit_internal_error_diagnostic(),
} Prevention
- Never use record-update syntax in module constants; construct records fully.
- Run `gleam check` so constant misuse is caught with a proper diagnostic.
- When adding AST variants, update every backend's constant printer.
When it happens
Trigger: A `Constant::RecordUpdate` node reaches `constant_expression` in the JavaScript backend — e.g. a record update expression `..thing` used where a constant is expected (module constant, bit array size, or similar) that earlier validation failed to reject.
Common situations: Writing a module-level constant that uses record-update syntax; compiler regression where constant lowering missed the RecordUpdate variant.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Invalid bit array segment type reached code generation
- invalid constants should not reach code generation
- invalid expressions should not reach code generation
- todo constants should not reach code generation
- case with no subjects
AI-assisted analysis of gleam-lang/gleam@49f8762da5 (2026-09-14).
Data as JSON: /api/errors/c4d79eb2fc49a9bc.
Report an issue: GitHub.
Appendix: source
Thrown at compiler-core/src/javascript/expression.rs:2859
| BinOp::SubInt
| BinOp::SubFloat
| BinOp::MultInt
| BinOp::MultFloat
| BinOp::DivInt
| BinOp::DivFloat
| BinOp::RemainderInt => {
unreachable!("invalid constant operator made it to code generation")
}
BinOp::Concatenate => {
let left = self.constant_expression(arena, context, left);
let right = self.constant_expression(arena, context, right);
docvec![arena, left, SPACE_PLUS_SPACE_DOCUMENT, right]
}
},
Constant::RecordUpdate { .. } => {
panic!("record updates should not reach code generation")
}
Constant::Todo { .. } => {
panic!("todo constants should not reach code generation")
}
Constant::Invalid { .. } => {
panic!("invalid constants should not reach code generation")
}
}
}
fn constant_bit_array(
&mut self,
arena: &'doc DocumentArena<'a, 'doc>,
segments: &'a [TypedConstantBitArraySegment],
context: Context,
) -> Document<'a, 'doc> {
self.tracker.bit_array_literal_used = true;
let segments_array = array(View on GitHub (pinned to 49f8762da5)