{"record":{"id":"cb34fa290027105d","repo":"gleam-lang/gleam","slug":"invalid-expressions-should-not-reach-code-generation","errorCode":null,"errorMessage":"invalid expressions should not reach code generation","messagePattern":"invalid expressions should not reach code generation","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-core/src/javascript/expression.rs","lineNumber":531,"sourceCode":"                self.negate_with(arena, MINUS_SPACE_DOCUMENT, value)\n            }\n\n            TypedExpr::Echo {\n                expression,\n                message,\n                location,\n                ..\n            } => {\n                let expression = expression\n                    .as_ref()\n                    .expect(\"echo with no expression outside of pipe\");\n                let expresion_doc =\n                    self.not_in_tail_position(None, |this| this.wrap_expression(arena, expression));\n                self.echo(arena, expresion_doc, message.as_deref(), location)\n            }\n\n            TypedExpr::Invalid { .. } => {\n                panic!(\"invalid expressions should not reach code generation\")\n            }\n        };\n        if let Position::Statement = self.scope_position\n            && expression_requires_semicolon(expression)\n        {\n            document = document.append(arena, SEMICOLON_DOCUMENT);\n        }\n        if expression.handles_own_return() {\n            docvec![\n                arena,\n                self.source_map_tracker(arena, expression.location().start),\n                document\n            ]\n        } else {\n            docvec![\n                arena,\n                self.source_map_tracker(arena, expression.location().start),\n                self.wrap_return(arena, document)","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/gleam-lang/gleam/blob/49f8762da595eb3c8f576656a4200a142ca188c9/compiler-core/src/javascript/expression.rs#L513-L549","documentation":"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.","triggerScenarios":"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()`.","commonSituations":"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.","solutions":["Fix all syntax and type errors in the module before running code generation (run `gleam check` / the parse+typecheck passes first).","If using compiler internals, ensure you abort the pipeline when error_count > 0 instead of calling the JavaScript generator.","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."],"exampleFix":"// before (embedding the compiler)\nlet module = compile(src);\nlet js = javascript::compile(&module); // panics on Invalid nodes\n// after\nlet module = compile(src);\nif module.has_errors() { return Err(...); }\nlet js = javascript::compile(&module);","handlingStrategy":"validation","validationCode":"// gleam_core usage: abort before codegen if the module has errors\nif module.has_errors() || module.ast.iter().any(|e| matches!(e, TypedExpr::Invalid{..})) {\n    return Err(Error::parse_failed());\n}","typeGuard":"fn is_codegen_safe(expr: &TypedExpr) -> bool {\n    !matches!(expr, TypedExpr::Invalid { .. })\n}","tryCatchPattern":"match std::panic::catch_unwind(|| javascript::compile(&module)) {\n    Ok(doc) => doc,\n    Err(_) => report_internal_compiler_bug(),\n}","preventionTips":["Always run parse + typecheck and abort on error before invoking any backend codegen.","When embedding the compiler, treat panics as compiler bugs and capture panic messages for bug reports.","Keep Gleam compiler versions in sync across workspace tooling."],"tags":["compiler","panic","code-generation","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"49f8762da595eb3c8f576656a4200a142ca188c9","analyzedAt":"2026-09-14T11:14:59.388Z","contentChangedAt":"2026-09-14T11:14:59.388Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}