{"record":{"id":"c1799c007a8a0d00","repo":"sigoden/aichat","slug":"no-changes","errorCode":null,"errorMessage":"No changes","messagePattern":"No changes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/config/mod.rs","lineNumber":1402,"sourceCode":"            .with_context(|| format!(\"Failed to write to '{}'\", temp_file.display()))?;\n        let editor = config.read().editor()?;\n        edit_file(&editor, &temp_file)?;\n        let new_document_paths = tokio::fs::read_to_string(&temp_file)\n            .await\n            .with_context(|| format!(\"Failed to read '{}'\", temp_file.display()))?;\n        let new_document_paths = new_document_paths\n            .split('\\n')\n            .filter_map(|v| {\n                let v = v.trim();\n                if v.is_empty() {\n                    None\n                } else {\n                    Some(v.to_string())\n                }\n            })\n            .collect::<Vec<_>>();\n        if new_document_paths.is_empty() || new_document_paths == document_paths {\n            bail!(\"No changes\")\n        }\n        rag.refresh_document_paths(&new_document_paths, false, config, abort_signal)\n            .await?;\n        config.write().rag = Some(Arc::new(rag));\n        Ok(())\n    }\n\n    pub async fn rebuild_rag(config: &GlobalConfig, abort_signal: AbortSignal) -> Result<()> {\n        let mut rag = match config.read().rag.clone() {\n            Some(v) => v.as_ref().clone(),\n            None => bail!(\"No RAG\"),\n        };\n        let document_paths = rag.document_paths().to_vec();\n        rag.refresh_document_paths(&document_paths, true, config, abort_signal)\n            .await?;\n        config.write().rag = Some(Arc::new(rag));\n        Ok(())\n    }","sourceCodeStart":1384,"sourceCodeEnd":1420,"githubUrl":"https://github.com/sigoden/aichat/blob/82976d349ad97ac9aae0655ad631dace5e2a6385/src/config/mod.rs#L1384-L1420","documentation":"Thrown by `GlobalConfig::edit_rag_docs` in src/config/mod.rs:1402 after the user edits the temporary document-list file, when the resulting `new_document_paths` list is empty or identical to the existing `document_paths`. The library refuses to refresh the RAG index because there is nothing to change, treating a no-op edit as an error so callers don't silently re-embed unchanged data.","triggerScenarios":"Opening the temp file in the editor and saving without modifications; deleting every line before saving; an editor wrapper that writes the same content back (e.g. format-on-save producing identical paths).","commonSituations":"Users who open the doc-list just to inspect it and save; editors or scripts that touch the file without changing content; accidentally clearing the file.","solutions":["Add, remove, or modify at least one document path in the temp file before saving","If inspection was the goal, exit the editor without saving (or abort the command)","Programmatically pass a genuinely different document list to `rag.refresh_document_paths` instead of relying on the editor flow"],"exampleFix":"// before (unchanged list triggers the error)\nrag.refresh_document_paths(&document_paths, false, config, signal).await?;\n// after: verify the change first\nif new_paths.is_empty() || new_paths == old_paths {\n    return Ok(()); // treat as no-op instead of erroring\n}\nrag.refresh_document_paths(&new_paths, false, config, signal).await?;","handlingStrategy":"validation","validationCode":"let new_paths: Vec<String> = read_edited_list();\nif new_paths.is_empty() || new_paths == old_paths {\n    eprintln!(\"No changes made to the document list; nothing to refresh\");\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = config.edit_rag_docs(signal).await {\n    if e.to_string() == \"No changes\" {\n        return Ok(()); // treat as benign no-op\n    }\n    return Err(e.into());\n}","preventionTips":["Instruct users to actually modify the doc list or abort without saving","Disable format-on-save for the temp doc-list file so content stays identical when unedited","Compare lists programmatically before refreshing"],"tags":["rag","no-op","editor","documents"],"backgroundTag":"no-changes-detected","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"}