{"record":{"id":"23e8d346c29be0d3","repo":"gleam-lang/gleam","slug":"custom-type-must-have-at-least-one-definition-here","errorCode":null,"errorMessage":"Custom type must have at least one definition here","messagePattern":"Custom type must have at least one definition here","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-core/src/javascript.rs","lineNumber":539,"sourceCode":"        // Add start and end position source map trackers to the first and last\n        // definition in place. This is to prevent extra new lines from being added\n        // to the output Since each definition is a separate statement in the output.\n        let start_location = custom_type\n            .documentation\n            .as_ref()\n            // 3 is the length of the \"///\" documentation marker.\n            // Start is the index of the actual content, so we need to subtract\n            // the length of the marker.\n            .map_or(custom_type.location.start, |(start, _)| *start - 3);\n        let first_definition = definitions.remove(0);\n        definitions.insert(\n            0,\n            self.source_map_tracker(arena, start_location)\n                .append(arena, first_definition),\n        );\n        let last_definition = definitions\n            .pop()\n            .expect(\"Custom type must have at least one definition here\");\n        definitions.push(last_definition.append(\n            arena,\n            self.source_map_tracker(arena, custom_type.end_position),\n        ));\n\n        Some(definitions)\n    }\n\n    fn variant_definition(\n        &self,\n        arena: &'doc DocumentArena<'a, 'doc>,\n        constructor: &'a TypedRecordConstructor,\n        type_name: &'a str,\n        publicity: Publicity,\n    ) -> Document<'a, 'doc> {\n        let class_definition = self.variant_class_definition(arena, constructor, publicity);\n\n        // Singleton constants are used internally by the compiler, so they aren't","sourceCodeStart":521,"sourceCodeEnd":557,"githubUrl":"https://github.com/gleam-lang/gleam/blob/7e623aa83da3776faee50ca4ab9a6c40124acd95/compiler-core/src/javascript.rs#L521-L557","documentation":"While emitting a custom type with source-map tracking, the JS generator does `definitions.remove(0)` and then `definitions.pop().expect(\"Custom type must have at least one definition here\")` (javascript.rs:539). The contract is that every custom type yields at least one definition document (the type declaration); an empty vec would already have panicked at remove(0) with index-out-of-bounds, so this expect specifically fires when exactly one element was consumed and the vec is somehow empty afterwards — an internal invariant break (ICE), not user configuration.","triggerScenarios":"A compiler bug where the statement generator produces an empty definitions list for a custom type on the JavaScript target with source maps enabled — unusual custom-type shapes after refactors, or version-skewed incremental caches feeding the generator stale AST metadata.","commonSituations":"Internal compiler error reports from `gleam build --target javascript` with sourcemap support; reproducing on a clean checkout distinguishes cache skew from a real codegen bug.","solutions":["Clear build artifacts and rebuild: `rm -rf build && gleam build --target javascript`.","Build without source maps / check whether toggling `--target` avoids the path, to confirm it is the JS sourcemap emitter.","Update to the newest gleam release; if it still reproduces, minimize the custom type involved and file an issue with the backtrace.","Embedders: run codegen in a subprocess (or std::panic::catch_unwind) so an ICE is reportable without killing your tool."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Build tools wrapping gleam: catch the ICE and surface a clean failure\nlet outcome = std::panic::catch_unwind(AssertUnwindSafe(|| {\n    gleam_core::build::main(paths, options_with_js_sourcemaps)\n}));\nmatch outcome {\n    Err(_) => {\n        eprintln!(\"gleam internal compiler error while emitting custom types;\\\n          run `rm -rf build` and retry, then report if it persists\");\n        std::process::exit(101);\n    }\n    Ok(r) => r?,\n}","preventionTips":["Clear `build/` after every gleam upgrade before JS-target builds with sourcemaps.","Reproduce ICEs on clean checkouts; attach the backtrace and module source when filing upstream issues.","Drive release builds through a subprocess so compiler ICEs fail the build visibly instead of crashing the orchestrator."],"tags":["panic","internal-compiler-error","javascript","codegen","custom-types","source-maps","gleam-core"],"backgroundTag":"compiler-internal-error","analyzedSha":"7e623aa83da3776faee50ca4ab9a6c40124acd95","analyzedAt":"2026-08-17T00:07:02.091Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}