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

  1. Rewrite the constant to not use record-update syntax (construct the record fully inside the constant).
  2. Move the record update out of constant position into a function body, where it is supported.
  3. 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

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


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)