{"record":{"id":"df341730d73872f7","repo":"Hmbown/CodeWhale","slug":"automationeditorinvalidworkspace","errorCode":null,"errorMessage":"AutomationEditorInvalidWorkspace","messagePattern":"AutomationEditorInvalidWorkspace","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/views/automations/editor.rs","lineNumber":648,"sourceCode":"                .to_string()\n        });\n        let workspace_changed = old_workspace.as_deref() != Some(self.workspace.value.as_str());\n        let mut cwds = self\n            .original\n            .as_ref()\n            .map(|r| r.cwds.clone())\n            .unwrap_or_default();\n        // Leave old multi-workspace definitions intact; the existing scheduler\n        // executes their first workspace. Editing that field keeps the tail.\n        if workspace_changed {\n            let path = PathBuf::from(self.workspace.value.trim());\n            let path = if path.is_absolute() {\n                path\n            } else {\n                self.workspace_root.join(path)\n            };\n            if self.workspace.value.trim().is_empty() || !path.is_dir() {\n                anyhow::bail!(\n                    \"{}\",\n                    tr(self.locale, MessageId::AutomationEditorInvalidWorkspace)\n                );\n            }\n            let path = path.canonicalize()?;\n            if cwds.is_empty() {\n                cwds.push(path);\n            } else {\n                cwds[0] = path;\n            }\n        }\n        if let Some(original) = &self.original {\n            let latest = manager.get_automation(&original.id)?;\n            let request = UpdateAutomationRequest {\n                name: (self.name.value != original.name).then(|| self.name.value.clone()),\n                prompt: (self.prompt.value != original.prompt).then(|| self.prompt.value.clone()),\n                rrule: self.schedule_changed.then_some(rrule),\n                cwds: workspace_changed.then_some(cwds),","sourceCodeStart":630,"sourceCodeEnd":666,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/views/automations/editor.rs#L630-L666","documentation":"AutomationEditor::save validates that the workspace field is non-empty and that the resolved path (absolute, or joined with workspace_root) is an existing directory; otherwise it throws the localized AutomationEditorInvalidWorkspace message. The editor cannot persist an automation whose cwd points at nothing usable.","triggerScenarios":"Saving the automation editor while workspace.value.trim() is empty, or the entered path (after joining with workspace_root when relative) is not a directory (missing, deleted, or a file).","commonSituations":"User cleared the workspace field; typed a typo'd path; referenced a directory that was deleted or renamed after the editor opened; entered a relative path that doesn't resolve under workspace_root.","solutions":["Enter an existing directory path in the workspace field (or leave a valid default) before saving.","Verify the directory still exists on disk; recreate it if it was deleted.","Use an absolute path, or ensure the relative path resolves under workspace_root."],"exampleFix":"// before\npath: \"~/projs\"\n\n// after (must exist and be a directory)\npath: \"/home/user/projs\"","handlingStrategy":"validation","validationCode":"let p = editor.workspace.value.trim();\nlet path = if Path::new(p).is_absolute() { PathBuf::from(p) } else { editor.workspace_root.join(p) };\nlet ok = !p.is_empty() && path.is_dir();","typeGuard":null,"tryCatchPattern":"match editor.save() {\n    Err(e) if e.to_string().contains(\"workspace\") => show_workspace_error_and_refocus_field(),\n    other => other?,\n}","preventionTips":["Validate the workspace field on every keystroke, not only at save.","Offer a directory picker so paths always exist.","Re-check the directory at save time — it may have been deleted after the editor opened.","Show resolved absolute path for relative inputs."],"tags":["automation-editor","validation","workspace","ui"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T10:30:35.592Z"}