windmill-labs/windmill · error

Module '{}': {}

Error message

Module '{}': {}

What it means

Wraps any error produced while obtaining a flow module's value (its inner job/payload) during flow traversal, prefixing it with the module id so callers can tell which module of the flow failed. It is a context-preserving wrapper, not a distinct failure mode: the root cause is whatever get_value() returned.

Source

Thrown at backend/windmill-types/src/flows.rs:710

        #[derive(Deserialize)]
        pub struct FlowModuleValueType<'a> {
            pub r#type: &'a str,
        }

        serde_json::from_str::<FlowModuleValueType>(self.value.get())
            .map_err(|e| anyhow::anyhow!("{}", e))
            .map(|x| x.r#type)
    }

    pub fn traverse_modules<C: FnMut(&FlowModule) -> anyhow::Result<()>>(
        modules: &Vec<FlowModule>,
        cb: &mut C,
    ) -> anyhow::Result<()> {
        for module in modules {
            cb(module)?;
            let module_value = module
                .get_value()
                .map_err(|e| anyhow::anyhow!("Module '{}': {}", module.id, e))?;
            Self::traverse_module_value(&module_value, cb)?;
        }
        Ok(())
    }

    fn traverse_module_value<C: FnMut(&FlowModule) -> anyhow::Result<()>>(
        module_value: &FlowModuleValue,
        cb: &mut C,
    ) -> anyhow::Result<()> {
        match module_value {
            FlowModuleValue::ForloopFlow { modules, .. }
            | FlowModuleValue::WhileloopFlow { modules, .. } => {
                Self::traverse_modules(modules, cb)?;
            }
            FlowModuleValue::BranchOne { branches, default, .. } => {
                for branch in branches {
                    Self::traverse_modules(&branch.modules, cb)?;
                }

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read the inner error after 'Module <id>': it names the real cause
  2. Inspect the module with that id in the flow editor and fix its value/expr
  3. Re-deploy the flow from a known-good definition
  4. Check for windmill version mismatches between exporter and importer
Defensive patterns

Strategy: try-catch

Try / catch

// Rust
match flow.traverse(&mut cb) {
    Err(e) if e.to_string().starts_with("Module '") => {
        let module_id = e.to_string().split('\'').nth(1).unwrap_or("?");
        eprintln!("fix flow module {module_id}: {e:#}");
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling Flow::traverse / traverse_module_value on a flow whose module get_value() fails — e.g. a module value cannot be deserialized or resolved.

Common situations: Flows edited by hand or by scripts containing corrupt module values; flows imported from other instances with incompatible payload shapes; schema changes to FlowModuleValue after a version upgrade.

Related errors


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