windmill-labs/windmill · error

Could not parse embedded manifest: {}

Error message

Could not parse embedded manifest: {}

What it means

Windmill's Rust script parser (`windmill-parser-rust`) reads an embedded Cargo manifest from the script source — either a `// cargo-deps:` comment line (DepList) or a ```Cargo.toml``` code block (Toml) — and converts it into a TOML table. `into_toml` wraps any TOML deserialization failure of that embedded manifest with this message. It is thrown at script-parse time, before the script ever runs.

Source

Thrown at backend/parsers/windmill-parser-rust/src/lib.rs:157

            let typ = parse_pat_type(s.ty.clone());
            (otyp, typ, name)
        }
    }
}

#[derive(Debug, PartialEq)]
enum Manifest {
    Toml(String),
    DepList(String),
}

impl Manifest {
    pub fn into_toml(self) -> anyhow::Result<toml::value::Table> {
        match self {
            Manifest::Toml(s) => toml::from_str(&s),
            Manifest::DepList(s) => Manifest::dep_list_to_toml(&s),
        }
        .map_err(|e| anyhow!("Could not parse embedded manifest: {}", e))
    }

    fn dep_list_to_toml(s: &str) -> ::std::result::Result<toml::value::Table, toml::de::Error> {
        let mut r = String::new();
        r.push_str("[dependencies]\n");
        for dep in s.trim().split(',') {
            // If there's no version specified, add one.
            match dep.contains('=') {
                true => {
                    r.push_str(dep);
                    r.push('\n');
                }
                false => {
                    r.push_str(dep);
                    r.push_str("=\"*\"\n");
                }
            }
        }

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read the inner TOML error after the colon in the message; it names the offending line/entry of the embedded manifest.
  2. If using the `// cargo-deps:` shorthand, make it a comma-separated list of `crate=version` (version optional): `// cargo-deps: serde=1.0 reqwest` — no braces, no features syntax.
  3. If using a ```Cargo.toml code block, validate it as standalone TOML (e.g. paste into a TOML linter) with a proper `[dependencies]` section.
  4. Remove the embedded manifest entirely to fall back to the default manifest if dependencies aren't needed.

Example fix

// before — invalid: braces/features not supported in the shorthand line
// cargo-deps: serde={version="1", features=["derive"]},

// after
// cargo-deps: serde=1.0
// (or move features into a ```Cargo.toml code block)
Defensive patterns

Strategy: validation

Validate before calling

// Rust: validate the embedded manifest before handing the script to the parser
fn valid_embedded_manifest(src: &str) -> bool {
    if let Some(line) = src.lines().find(|l| l.trim().to_lowercase().starts_with("//cargo-deps:")) {
        return line.split(':').nth(1).map_or(false, |deps| {
            deps.split(',').all(|d| {
                let d = d.trim();
                d.is_empty() || d.split('=').count() <= 2 && !d.starts_with('=')
            })
        });
    }
    true // no embedded manifest -> default used
}

Try / catch

// Rust
match parse_rust_sig(&code) {
    Ok(sig) => /* use sig */,
    Err(e) if e.to_string().contains("Could not parse embedded manifest") => {
        eprintln!("Fix the // cargo-deps: line or ```Cargo.toml block: {e}");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Called via `into_toml` when: (1) a `// cargo-deps:` line contains entries that produce invalid TOML after dep_list_to_toml rewrites them (e.g. an entry with stray characters, a trailing comma producing an empty entry like `foo="*"` is fine but `=` with empty key/value is not), or (2) a ```Cargo.toml fenced block in the script is not valid TOML (missing brackets around `[dependencies]`, wrong indentation producing bare values, unclosed strings).

Common situations: Hand-editing the cargo-deps line and leaving a trailing comma or a `dep=` entry with an empty version; copying a Cargo.toml block that includes non-TOML prose or markdown; Windows line endings combined with inline comments confusing the shorthand parser; using crate features syntax `serde={version="1",features=["derive"]}` on a single comment line where the parser expects `name=version` only.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/9e690ca1fd994806. Report an issue: GitHub.