{"record":{"id":"9522e74d4f160fd4","repo":"windmill-labs/windmill","slug":"step-references-which-is-not-a-workspac","errorCode":null,"errorMessage":"step '{}' references '{}', which is not a workspace path (expected u/, f/, g/ or hub/). Absolute or local filesystem paths are not allowed in flow steps.","messagePattern":"step '(.+?)' references '(.+?)', which is not a workspace path \\(expected u/, f/, g/ or hub/\\)\\. Absolute or local filesystem paths are not allowed in flow steps\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-types/src/flows.rs","lineNumber":250,"sourceCode":"\nfn validate_flow_value<'de, D>(deserializer: D) -> Result<Box<RawValue>, D::Error>\nwhere\n    D: Deserializer<'de>,\n{\n    let raw_value = Box::<RawValue>::deserialize(deserializer)?;\n\n    let flow_value: FlowValue = serde_json::from_str(raw_value.get())\n        .map_err(|e| serde::de::Error::custom(format!(\"Invalid flow value: {}\", e)))?;\n\n    let mut validate_module = |module: &FlowModule| -> anyhow::Result<()> {\n        if let Some(ref retry) = module.retry {\n            validate_retry(retry, &module.id)?;\n        }\n        if let Ok(FlowModuleValue::Script { path, .. } | FlowModuleValue::Flow { path, .. }) =\n            module.get_value()\n        {\n            if !is_workspace_runnable_path(&path) {\n                return Err(anyhow::anyhow!(\n                    \"step '{}' references '{}', which is not a workspace path (expected u/, \\\n                     f/, g/ or hub/). Absolute or local filesystem paths are not allowed in \\\n                     flow steps.\",\n                    module.id,\n                    path\n                ));\n            }\n        }\n        Ok(())\n    };\n\n    // The API is the authoritative guard (it can be called directly, bypassing the CLI), so\n    // it must cover every step that resolves a path: the main modules AND the failure /\n    // preprocessor modules (which can themselves be sub-flows/loops/branches).\n    let extra_modules: Vec<FlowModule> = flow_value\n        .failure_module\n        .iter()\n        .chain(flow_value.preprocessor_module.iter())","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-types/src/flows.rs#L232-L268","documentation":"Flow validation enforces that script and flow module paths reference workspace runnables (paths starting with u/, f/, g/ or hub/). Absolute paths like /home/user/x.py or local filesystem references are rejected because the engine can only resolve workspace-hosted code, preventing accidental or unsafe local-path references.","triggerScenarios":"Saving a flow where a Script or Flow module's `path` is e.g. '/scripts/foo.py', 'file://...', or a bare name without a workspace prefix — caught by validate_flow_value on create/update.","commonSituations":"Migrating scripts from local directories into flows, copying paths from CLI invocations of local files, typos omitting the u/ or f/ prefix, or generated flows from AI/tooling that emit raw file paths.","solutions":["Prefix the path correctly: 'u/<user>/<script>' for user scripts, 'f/<folder>/<script>' for folder scripts, or 'hub/...' for hub scripts","Upload the local script to the workspace first, then reference its workspace path in the module","Fix the module path in the flow editor and re-save"],"exampleFix":"// before\n{\"type\": \"script\", \"path\": \"/home/me/etl.py\"}\n// after\n{\"type\": \"script\", \"path\": \"u/me/etl\"}","handlingStrategy":"validation","validationCode":"function isWorkspaceRunnablePath(p) {\n  return /^(u|f|g|hub)\\//.test(p);\n}\n// before saving: flow.modules.forEach(m => {\n//   if ((m.value.type === \"script\" || m.value.type === \"flow\") && !isWorkspaceRunnablePath(m.value.path))\n//     throw new Error(`module ${m.id}: path ${m.value.path} is not a workspace path`);\n// });","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Upload local scripts to the workspace first, then reference them by workspace path","Never paste local/absolute filesystem paths into flow step configs","Lint generated flow JSON for path prefixes before deploy"],"tags":["validation","flows","path-validation","workspace"],"backgroundTag":"invalid-workspace-path","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"}