{"record":{"id":"b3cb721c5001d32e","repo":"Hmbown/CodeWhale","slug":"tr-self-locale-messageid-automationeditorinvalidworkspace","errorCode":null,"errorMessage":"tr(self.locale, MessageId::AutomationEditorInvalidWorkspace)","messagePattern":"tr\\(self\\.locale, MessageId::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/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/tui/views/automations/editor.rs#L630-L666","documentation":"Thrown in `AutomationEditor::save` when the workspace field is blank or the resolved path is not an existing directory. The editor resolves the workspace value against the workspace root when it is not absolute, then validates it before saving the automation. The message is the localized `AutomationEditorInvalidWorkspace` string.","triggerScenarios":"Calling `save` with `workspace.value` trimmed-empty, or with a path (joined onto `workspace_root` if relative) that fails `path.is_dir()` — e.g. a typo'd directory, a file path, or a directory that no longer exists.","commonSituations":"Typing a relative workspace path while running the TUI from a different cwd; moving/renaming the automation's target directory after the editor was opened; leaving the workspace field blank; passing a file instead of a directory.","solutions":["Enter an absolute path to an existing directory in the workspace field","Create the target directory before saving (mkdir -p the path)","Verify the path exists and is a directory (not a file) from the shell","Reopen the editor after fixing the path so the workspace_root join resolves correctly"],"exampleFix":"// before\nworkspace = \"~/project/src\"  // points at a file\n// after\nworkspace = \"/home/user/projects/src\"  // absolute, existing directory","handlingStrategy":"validation","validationCode":"let p = if Path::new(&ws).is_absolute() { PathBuf::from(&ws) } else { root.join(&ws) };\nif ws.trim().is_empty() || !p.is_dir() { return Err(\"invalid workspace\"); }","typeGuard":null,"tryCatchPattern":"match save_result {\n    Err(e) if e.to_string().contains(\"Invalid workspace\") => {\n        // show the localized message and refocus the workspace field\n    }\n    other => other?,\n}","preventionTips":["Enter absolute paths to existing directories","Verify the directory still exists before saving","Use a path picker rather than free-text input where possible","Reopen the editor after moving directories on disk"],"tags":["automation","validation","path","rust"],"backgroundTag":"directory-not-found","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T06:17:15.046Z"}