gleam-lang/gleam · error

invalid expressions should not reach code generation

Error message

invalid expressions should not reach code generation

What it means

The Gleam JavaScript code generator asserts that an `TypedExpr::Invalid` expression (a placeholder produced by the parser/type checker after a syntax or type error) never reaches code generation. Hitting this panic means an internal compiler invariant was broken: error recovery failed to stop compilation before the JavaScript backend ran.

Solutions

  1. Fix all syntax and type errors in the module before running code generation (run `gleam check` / the parse+typecheck passes first).
  2. If using compiler internals, ensure you abort the pipeline when error_count > 0 instead of calling the JavaScript generator.
  3. If all your code is valid and this still fires, it is a compiler bug — report it to the Gleam repository with a minimal reproducing module.

Example fix

// before (embedding the compiler)
let module = compile(src);
let js = javascript::compile(&module); // panics on Invalid nodes
// after
let module = compile(src);
if module.has_errors() { return Err(...); }
let js = javascript::compile(&module);
Defensive patterns

Strategy: validation

Validate before calling

// gleam_core usage: abort before codegen if the module has errors
if module.has_errors() || module.ast.iter().any(|e| matches!(e, TypedExpr::Invalid{..})) {
    return Err(Error::parse_failed());
}

Type guard

fn is_codegen_safe(expr: &TypedExpr) -> bool {
    !matches!(expr, TypedExpr::Invalid { .. })
}

Try / catch

match std::panic::catch_unwind(|| javascript::compile(&module)) {
    Ok(doc) => doc,
    Err(_) => report_internal_compiler_bug(),
}

Prevention

When it happens

Trigger: Calling the JavaScript code generation pass on a module whose AST still contains `TypedExpr::Invalid` nodes — i.e. generating code for a module that was not fully parsed/type-checked, or using compiler internals/library APIs to feed a partially-invalid AST straight into `expression()`.

Common situations: Embedding the Gleam compiler as a library (e.g. in tooling or LSP-like integrations) and invoking codegen without first checking for parse/type errors; compiler bugs where error recovery produced an Invalid node that wasn't pruned.

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@49f8762da5 (2026-09-14). Data as JSON: /api/errors/cb34fa290027105d. Report an issue: GitHub.

Appendix: source

Thrown at compiler-core/src/javascript/expression.rs:531

                self.negate_with(arena, MINUS_SPACE_DOCUMENT, value)
            }

            TypedExpr::Echo {
                expression,
                message,
                location,
                ..
            } => {
                let expression = expression
                    .as_ref()
                    .expect("echo with no expression outside of pipe");
                let expresion_doc =
                    self.not_in_tail_position(None, |this| this.wrap_expression(arena, expression));
                self.echo(arena, expresion_doc, message.as_deref(), location)
            }

            TypedExpr::Invalid { .. } => {
                panic!("invalid expressions should not reach code generation")
            }
        };
        if let Position::Statement = self.scope_position
            && expression_requires_semicolon(expression)
        {
            document = document.append(arena, SEMICOLON_DOCUMENT);
        }
        if expression.handles_own_return() {
            docvec![
                arena,
                self.source_map_tracker(arena, expression.location().start),
                document
            ]
        } else {
            docvec![
                arena,
                self.source_map_tracker(arena, expression.location().start),
                self.wrap_return(arena, document)

View on GitHub (pinned to 49f8762da5)