{"record":{"id":"cbfd20d6b7ba587e","repo":"sigoden/aichat","slug":"no-macro","errorCode":null,"errorMessage":"No macro","messagePattern":"No macro","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/config/mod.rs","lineNumber":1596,"sourceCode":"        list_file_names(Self::macros_dir(), \".yaml\")\n    }\n\n    pub fn load_macro(name: &str) -> Result<Macro> {\n        let path = Self::macro_file(name);\n        let err = || format!(\"Failed to load macro '{name}' at '{}'\", path.display());\n        let content = read_to_string(&path).with_context(err)?;\n        let value: Macro = serde_yaml::from_str(&content).with_context(err)?;\n        Ok(value)\n    }\n\n    pub fn has_macro(name: &str) -> bool {\n        let names = Self::list_macros();\n        names.contains(&name.to_string())\n    }\n\n    pub fn new_macro(&mut self, name: &str) -> Result<()> {\n        if self.macro_flag {\n            bail!(\"No macro\");\n        }\n        let ans = Confirm::new(\"Create a new macro?\")\n            .with_default(true)\n            .prompt()?;\n        if ans {\n            let macro_path = Self::macro_file(name);\n            ensure_parent_exists(&macro_path)?;\n            let editor = self.editor()?;\n            edit_file(&editor, &macro_path)?;\n        } else {\n            bail!(\"No macro\");\n        }\n        Ok(())\n    }\n\n    pub fn apply_prelude(&mut self) -> Result<()> {\n        if self.macro_flag || !self.state().is_empty() {\n            return Ok(());","sourceCodeStart":1578,"sourceCodeEnd":1614,"githubUrl":"https://github.com/sigoden/aichat/blob/82976d349ad97ac9aae0655ad631dace5e2a6385/src/config/mod.rs#L1578-L1614","documentation":"Thrown by GlobalConfig::new_macro() when `self.macro_flag` is true, i.e. the tool is already running in the middle of macro creation/editing. It prevents recursively or erroneously opening a new macro editor while a macro operation is in progress.","triggerScenarios":"Calling new_macro(name) while macro_flag is set — typically by invoking the macro-creation command from inside a macro/prelude-driven session or re-entrant command evaluation.","commonSituations":"A prelude (repl_prelude/cmd_prelude) or session state referencing macro creation while macro mode is already active; scripting nested macro edits.","solutions":["Do not invoke new_macro while a macro operation is already in progress.","Clear/complete the current macro session (macro_flag reset) before creating another macro.","Remove macro-creation commands from prelude or session replay content."],"exampleFix":"// before\nconfig.new_macro(\"greet\")?;\n// after\nif !config.read().macro_flag {\n    config.write().new_macro(\"greet\")?;\n} else {\n    eprintln!(\"A macro operation is already in progress\");\n}","handlingStrategy":"validation","validationCode":"if config.read().macro_flag { return Err(anyhow!(\"macro operation already in progress\")); }","typeGuard":null,"tryCatchPattern":"match config.new_macro(name) { Err(e) if e.to_string() == \"No macro\" => eprintln!(\"Cannot nest macro creation\"), other => other?, }","preventionTips":["Do not invoke macro commands from prelude/session replay","Track macro_flag in scripts that chain macro operations","Avoid re-entrant command evaluation during macro editing"],"tags":["macro","reentrant","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"82976d349ad97ac9aae0655ad631dace5e2a6385","analyzedAt":"2026-09-09T18:33:06.139Z","contentChangedAt":"2026-09-09T18:33:06.139Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}