gleam-lang/gleam · error

Custom type must have at least one definition here

Error message

Custom type must have at least one definition here

What it means

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.

Source

Thrown at compiler-core/src/javascript.rs:539

        // Add start and end position source map trackers to the first and last
        // definition in place. This is to prevent extra new lines from being added
        // to the output Since each definition is a separate statement in the output.
        let start_location = custom_type
            .documentation
            .as_ref()
            // 3 is the length of the "///" documentation marker.
            // Start is the index of the actual content, so we need to subtract
            // the length of the marker.
            .map_or(custom_type.location.start, |(start, _)| *start - 3);
        let first_definition = definitions.remove(0);
        definitions.insert(
            0,
            self.source_map_tracker(arena, start_location)
                .append(arena, first_definition),
        );
        let last_definition = definitions
            .pop()
            .expect("Custom type must have at least one definition here");
        definitions.push(last_definition.append(
            arena,
            self.source_map_tracker(arena, custom_type.end_position),
        ));

        Some(definitions)
    }

    fn variant_definition(
        &self,
        arena: &'doc DocumentArena<'a, 'doc>,
        constructor: &'a TypedRecordConstructor,
        type_name: &'a str,
        publicity: Publicity,
    ) -> Document<'a, 'doc> {
        let class_definition = self.variant_class_definition(arena, constructor, publicity);

        // Singleton constants are used internally by the compiler, so they aren't

View on GitHub (pinned to 7e623aa83d)

Solutions

  1. Clear build artifacts and rebuild: `rm -rf build && gleam build --target javascript`.
  2. Build without source maps / check whether toggling `--target` avoids the path, to confirm it is the JS sourcemap emitter.
  3. Update to the newest gleam release; if it still reproduces, minimize the custom type involved and file an issue with the backtrace.
  4. Embedders: run codegen in a subprocess (or std::panic::catch_unwind) so an ICE is reportable without killing your tool.
Defensive patterns

Strategy: try-catch

Try / catch

// Build tools wrapping gleam: catch the ICE and surface a clean failure
let outcome = std::panic::catch_unwind(AssertUnwindSafe(|| {
    gleam_core::build::main(paths, options_with_js_sourcemaps)
}));
match outcome {
    Err(_) => {
        eprintln!("gleam internal compiler error while emitting custom types;\
          run `rm -rf build` and retry, then report if it persists");
        std::process::exit(101);
    }
    Ok(r) => r?,
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gleam-lang/gleam@7e623aa83d (2026-08-17). Data as JSON: /api/errors/23e8d346c29be0d3. Report an issue: GitHub.