{"record":{"id":"66a9984ddd7ff7f5","repo":"sigoden/aichat","slug":"no-sources","errorCode":null,"errorMessage":"No sources","messagePattern":"No sources","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src/config/mod.rs","lineNumber":1426,"sourceCode":"    }\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    }\n\n    pub fn rag_sources(config: &GlobalConfig) -> Result<String> {\n        match config.read().rag.as_ref() {\n            Some(rag) => match rag.get_last_sources() {\n                Some(v) => Ok(v),\n                None => bail!(\"No sources\"),\n            },\n            None => bail!(\"No RAG\"),\n        }\n    }\n\n    pub fn rag_info(&self) -> Result<String> {\n        if let Some(rag) = &self.rag {\n            rag.export()\n        } else {\n            bail!(\"No RAG\")\n        }\n    }\n\n    pub fn exit_rag(&mut self) -> Result<()> {\n        self.rag.take();\n        Ok(())\n    }\n","sourceCodeStart":1408,"sourceCodeEnd":1444,"githubUrl":"https://github.com/sigoden/aichat/blob/82976d349ad97ac9aae0655ad631dace5e2a6385/src/config/mod.rs#L1408-L1444","documentation":"Thrown by `GlobalConfig::rag_sources` in src/config/mod.rs:1426 when a RAG session IS active but `rag.get_last_sources()` returns `None` — meaning no retrieval has produced citation sources yet (e.g. no query has been answered through the RAG since it was loaded). It is distinct from the 'No RAG' branch in the same function, which fires when no RAG is loaded at all.","triggerScenarios":"Calling `Config::rag_sources(config)` right after entering RAG mode, before any chat/query has run through the RAG; after a query that retrieved nothing; after the sources cache was cleared on a fresh `Rag::load`.","commonSituations":"Users asking for '.last sources' (or equivalent) immediately after loading a RAG; scripts that fetch sources before the first RAG-backed answer; queries whose embedding matched no documents.","solutions":["Run at least one RAG-backed query first, then request the sources","If the query legitimately matched nothing, treat 'no sources' as an expected empty state rather than an error","Check `rag.get_last_sources().is_some()` before calling and fall back to a friendly message"],"exampleFix":"// before\nlet sources = Config::rag_sources(&config)?;\n// after\nmatch config.read().rag.as_ref().and_then(|r| r.get_last_sources()) {\n    Some(s) => println!(\"{s}\"),\n    None => println!(\"No sources yet — run a RAG query first\"),\n}","handlingStrategy":"fallback","validationCode":"let has_sources = config.read().rag.as_ref()\n    .and_then(|r| r.get_last_sources()).is_some();\nif !has_sources {\n    eprintln!(\"No sources yet — run a RAG-backed query first\");\n}","typeGuard":null,"tryCatchPattern":"match Config::rag_sources(&config) {\n    Ok(s) => println!(\"{s}\"),\n    Err(e) if e.to_string() == \"No sources\" => println!(\"(no sources recorded yet)\"),\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Only request sources after at least one successful RAG query","Treat empty sources as an expected state in UI/scripts","Verify retrieval returned documents before promising citations"],"tags":["rag","sources","empty-state"],"backgroundTag":"empty-result-set","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"}