{"record":{"id":"59c7c100179ba5f1","repo":"windmill-labs/windmill","slug":"error-59c7c1","errorCode":null,"errorMessage":"{}","messagePattern":"\\{\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-types/src/flows.rs","lineNumber":647,"sourceCode":"}\n\n#[derive(Deserialize)]\npub struct BranchWithSkipFailures {\n    pub skip_failure: Option<bool>,\n}\n\n#[derive(Deserialize)]\npub struct FlowModuleWithBranches {\n    pub branches: Vec<BranchWithSkipFailures>,\n}\n\nimpl FlowModule {\n    pub fn id_append(&mut self, s: &str) {\n        self.id = format!(\"{}-{}\", self.id, s);\n    }\n    pub fn get_value(&self) -> anyhow::Result<FlowModuleValue> {\n        serde_json::from_str::<FlowModuleValue>(self.value.get())\n            .map_err(|e| anyhow::anyhow!(\"{}\", e))\n    }\n\n    pub fn get_value_with_skip_failures(&self) -> anyhow::Result<FlowModuleValueWithSkipFailures> {\n        serde_json::from_str::<FlowModuleValueWithSkipFailures>(self.value.get())\n            .map_err(|e| anyhow::anyhow!(\"{}\", e))\n    }\n\n    pub fn get_branches_skip_failures(&self) -> anyhow::Result<FlowModuleWithBranches> {\n        serde_json::from_str::<FlowModuleWithBranches>(self.value.get())\n            .map_err(|e| anyhow::anyhow!(\"{}\", e))\n    }\n\n    pub fn is_flow(&self) -> bool {\n        self.get_type().is_ok_and(|x| x == \"flow\")\n    }\n\n    pub fn get_value_with_parallel(&self) -> anyhow::Result<FlowModuleValueWithParallel> {\n        serde_json::from_str::<FlowModuleValueWithParallel>(self.value.get())","sourceCodeStart":629,"sourceCodeEnd":665,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-types/src/flows.rs#L629-L665","documentation":"FlowModule::get_value deserializes the module's raw `value` JSON column into FlowModuleValue. Since the column is stored as untyped JSON, any shape mismatch (unknown or invalid 'type' discriminant, missing fields for that type, malformed JSON) surfaces as the raw serde error wrapped with this empty message.","triggerScenarios":"Any code path calling flow_module.get_value() on a module whose stored JSON doesn't deserialize into FlowModuleValue — e.g. flow execution, editing, or traversal after a schema change or corrupt write.","commonSituations":"Old flow modules saved before a FlowModuleValue enum variant changed name/shape, hand-edited module JSON, corrupt DB rows, or deploys from mismatched frontend/backend versions.","solutions":["Read the wrapped serde message for the exact field/discriminant mismatch","Re-save the module from the flow editor so the current schema serializes it","Fix the 'type' field to a valid FlowModuleValue variant and include its required fields","Check for frontend/backend version skew after an upgrade"],"exampleFix":"// before\n{\"type\": \"scrip\", \"path\": \"u/x/y\"}\n// after\n{\"type\": \"script\", \"input_transforms\": {}, \"path\": \"u/x/y\"}","handlingStrategy":"validation","validationCode":"function moduleValueTypeIsValid(moduleValueJson) {\n  const VALID = [\"rawscript\",\"script\",\"flow\",\"branchall\",\"branchone\",\"forloop\",\"whileloop\",\"loop\",\"aiagent\",\"failure\",\"approval\",\"sleep\",\"wait\",\"http\",\"websocket\",\"graphql\",\"input\",\"identity\",\"dependabot\"];\n  try { const v = JSON.parse(moduleValueJson); return VALID.includes(v?.type); } catch { return false; }\n}","typeGuard":"function hasModuleType(m) {\n  try { return typeof JSON.parse(m.value).type === \"string\"; } catch { return false; }\n}","tryCatchPattern":"match module.get_value() {\n    Ok(v) => use_value(v),\n    Err(e) => log::error!(\"corrupt module {}: {}\", module.id, e), // serde detail included\n}","preventionTips":["Re-save flows through the editor after version upgrades","Never hand-edit flow module JSON in the database","Keep backend and frontend versions aligned"],"tags":["json","serde","deserialization","flows"],"backgroundTag":"schema-validation-failed","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}