{"record":{"id":"3ac838b78d2b4b45","repo":"gleam-lang/gleam","slug":"invalid-constants-can-not-be-in-an-untyped-ast","errorCode":null,"errorMessage":"invalid constants can not be in an untyped ast","messagePattern":"invalid constants can not be in an untyped ast","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-core/src/type_/constant.rs","lineNumber":553,"sourceCode":"                            .problems\n                            .error(convert_unify_error(error, message.location()));\n                    }\n                    Box::new(message)\n                });\n\n                // Constant todos always result in a compile time error, this\n                // way the developer has to remember to change them before\n                // running their code!\n                self.typer.problems.error(Error::TodoConstant { location });\n\n                Constant::Todo {\n                    location,\n                    type_,\n                    message,\n                }\n            }\n\n            Constant::Invalid { .. } => panic!(\"invalid constants can not be in an untyped ast\"),\n        }\n    }\n\n    fn infer_string_concatenation(\n        &mut self,\n        location: SrcSpan,\n        operator_start: u32,\n        left: UntypedConstant,\n        right: UntypedConstant,\n        operator: BinOp,\n    ) -> TypedConstant {\n        self.typer\n            .track_feature_usage(FeatureKind::ConstantStringConcatenation, location);\n        let left = self.do_infer(left);\n\n        if let Err(error) = unify(string(), left.type_()) {\n            self.typer.problems.error(\n                error","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/gleam-lang/gleam/blob/49f8762da595eb3c8f576656a4200a142ca188c9/compiler-core/src/type_/constant.rs#L535-L571","documentation":"An internal invariant panic in Gleam's constant inference (`constant.rs:535`, `do_infer`). Constants carrying `Constant::Invalid` are sentinel nodes produced by the parser/error-recovery for syntactically invalid constants; they should be filtered out before type inference runs. Reaching inference with one means the untyped AST still contains an error placeholder, so inference cannot proceed and panics.","triggerScenarios":"Type inference (`infer`, `do_infer`, `infer_record`, `infer_tuple`, `infer_list`, `infer_string_concatenation`) encounters a `Constant::Invalid` node — e.g. a module constant or record/tuple/list element whose constant expression failed to parse but was not dropped before typing.","commonSituations":"Compiling a module with a malformed constant (bad literal, invalid record constructor syntax) where error recovery leaves an `Invalid` placeholder in a nested constant position; compiler development adding new constant forms; compiler bugs where `Invalid` nodes propagate into nested structures.","solutions":["Fix the syntax error in the offending constant definition in your Gleam source — the compiler's error output should point near it.","Rewrite the constant with valid literal/constructor syntax and recompile.","If you believe the constant is valid, report a compiler bug with the source snippet — `Invalid` nodes should have produced a parse error or been filtered, not panicked.","If developing the compiler, ensure `Constant::Invalid` nodes are filtered from the AST before inference, or make `do_infer` return a type error instead of panicking."],"exampleFix":"// before (Gleam source with invalid constant)\nconst x: Int = not_a_valid_constant(]\n\n// after\nconst x: Int = 42","handlingStrategy":"validation","validationCode":"// Rust (compiler-side): filter invalid constants before inference\nlet constants: Vec<_> = constants\n    .into_iter()\n    .filter(|c| !matches!(c, Constant::Invalid { .. }))\n    .collect();","typeGuard":"fn is_inferable(c: &TypedConstant) -> bool {\n    !matches!(c, Constant::Invalid { .. })\n}","tryCatchPattern":"// Panics are not recoverable; gate inference on the guard\nif !is_inferable(constant) {\n    return; // or emit a diagnostic instead of inferring\n}","preventionTips":["Fix constant syntax errors reported by the parser before relying on type-check output.","Ensure error-recovery placeholders (`Constant::Invalid`) are pruned from the AST before the typing phase.","When adding new constant syntax, test that malformed forms produce diagnostics, not inference panics."],"tags":["ast","type-inference","internal-invariant","parser","panic"],"backgroundTag":"invalid-argument-value","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"}