gleam-lang/gleam · error

record updates should not reach code generation

Error message

record updates should not reach code generation

What it means

An internal compiler assertion: a Constant::RecordUpdate node reached find_referenced_private_functions during Erlang code generation. Record-update constants should be rejected or desugared by earlier compiler phases (parsing/type checking), so their presence in codegen means an invariant was broken.

Solutions

  1. Rewrite the constant without a record-update expression (construct the record fully and explicitly).
  2. Update gleam to the latest version; unsupported-constant handling may have been fixed.
  3. File a minimal reproducing example as a bug at github.com/gleam-lang/gleam.

Example fix

// before
pub const cfg = Config(..base_config, flag: True)
// after
pub const cfg = Config(field1: base_config.field1, flag: True)
Defensive patterns

Strategy: validation

Validate before calling

// Avoid record updates in constant positions before building
// grep for 'const' declarations containing '..' record-update syntax
grep -nE 'const\s+\w+\s*=.*\.\.' src/

Type guard

match constant { Constant::RecordUpdate { .. } => None, c => Some(c) }

Try / catch

let status = Command::new("gleam").args(["build"]).status()?;
if !status.success() { /* inspect compiler output */ }

Prevention

When it happens

Trigger: A record update expression used in a constant position (e.g. inside a pub const) survives to the erlang.rs code generator instead of being rejected earlier.

Common situations: Writing something like `pub const cfg = ..{ ..cfg, flag: True }` in a context where constant record updates are not supported; a compiler bug letting the construct slip through validation.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of gleam-lang/gleam@15b07c7830 (2026-09-14). Data as JSON: /api/errors/edca1179f17cdfc7. Report an issue: GitHub.

Appendix: source

Thrown at compiler-core/src/erlang.rs:4396

    let mut overridden_publicity = imbl::HashSet::new();

    for constant in &module.definitions.constants {
        if constant.publicity.is_importable() {
            find_referenced_private_functions(&constant.value, &mut overridden_publicity);
        }
    }
    overridden_publicity
}

fn find_referenced_private_functions(
    constant: &TypedConstant,
    already_found: &mut imbl::HashSet<EcoString>,
) {
    match constant {
        Constant::Todo { .. } => panic!("todo constants should not reach code generation"),
        Constant::Invalid { .. } => panic!("invalid constants should not reach code generation"),
        Constant::RecordUpdate { .. } => {
            panic!("record updates should not reach code generation")
        }

        Constant::Int { .. }
        | Constant::Float { .. }
        | Constant::String { .. }
        | Constant::BitArray { .. } => (),

        TypedConstant::Var {
            name, constructor, ..
        } => {
            if let Some(ValueConstructor { type_, .. }) = constructor.as_deref()
                && let Type::Fn { .. } = **type_
            {
                let _ = already_found.insert(name.clone());
            }
        }

        TypedConstant::Record { arguments, .. } => arguments

View on GitHub (pinned to 15b07c7830)