gleam-lang/gleam · error

packages.toml serialization

Error message

packages.toml serialization

What it means

write_to_disc serializes the resolved-packages map with toml::to_string and unwraps the result. Serialization only fails if the in-memory PackagesConfig contains values TOML cannot represent (e.g. mismatched value types injected by a manifest with unexpected shapes).

Solutions

  1. Delete the build directory (and regenerate manifest.toml with `gleam deps download`) to reset cached state
  2. Check manifest.toml for hand-edited entries with unusual value types and restore valid syntax
  3. Report to the Gleam repo with the manifest that triggers it — the panic indicates unvalidated data reaching the serializer
  4. Upgrade the compiler, as serializer input validation may have been fixed

Example fix

// before: hand-edited manifest entry with wrong value type
[dependencies.gleam_stdlib]
oversion = "0.38"
// after
[dependencies]
gleam_stdlib = ">= 0.38.0 and < 2.0.0"
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on cache, check manifest entries are well-formed TOML with valid versions
toml::from_str::<toml::Value>(&fs::read_to_string("manifest.toml")?)?;

Prevention

When it happens

Trigger: Writing build/packages.toml after resolution when a package entry contains a type the TOML serializer rejects — e.g. a None/null in a spot TOML forbids, or a struct field type mismatch from a hand-edited or corrupt manifest.

Common situations: A corrupted or hand-edited manifest.toml producing unexpected package entries; a compiler bug after a manifest format change; filesystem write permission issues are NOT this error (that fails later at fs::write with a normal error).

Related errors


AI-assisted analysis of gleam-lang/gleam@15b07c7830 (2026-09-14). Data as JSON: /api/errors/4c300d85794d696f. Report an issue: GitHub.

Appendix: source

Thrown at compiler-cli/src/dependencies.rs:712

        let path = paths.build_packages_toml();
        if !path.exists() {
            return Ok(Self {
                packages: HashMap::new(),
                git: HashMap::new(),
            });
        }
        let toml = fs::read(&path)?;
        toml::from_str(&toml).map_err(|error| Error::FileIo {
            action: FileIoAction::Parse,
            kind: FileKind::File,
            path: path.clone(),
            err: Some(error.to_string()),
        })
    }

    pub fn write_to_disc(&self, paths: &ProjectPaths) -> Result<()> {
        let path = paths.build_packages_toml();
        let toml = toml::to_string(&self).expect("packages.toml serialization");
        fs::write(&path, &toml)
    }

    pub fn from_manifest(manifest: &Manifest) -> Self {
        let packages = manifest
            .packages
            .iter()
            .map(|p| (p.name.clone(), p.version.clone()))
            .collect();
        let git = manifest
            .packages
            .iter()
            .filter_map(|p| match &p.source {
                ManifestPackageSource::Git { commit, path, .. } => Some((
                    p.name.clone(),
                    GitState {
                        commit: commit.clone(),
                        path: path.clone(),

View on GitHub (pinned to 15b07c7830)