sigoden/aichat · error

Unknown RAG

Error message

Unknown RAG '{name}'

What it means

Thrown by `GlobalConfig::use_rag` in src/config/mod.rs:1362 when an explicitly named RAG is requested but no RAG file exists at the path returned by `config.rag_file(name)`, AND the current working mode is a command (non-interactive) mode. In interactive mode the library instead initializes a brand-new RAG with that name; in cmd mode it fails fast so scripts get a clear 'unknown RAG' signal.

Solutions

  1. Create the RAG first by running the same command in interactive mode (it will initialize it), or use the rag-creation command
  2. Fix the RAG name typo / point to an existing RAG file
  3. Copy or regenerate the RAG file at the expected `rag_file(name)` path before running the command

Example fix

// before (cmd mode, RAG never created)
config.use_rag(Some("mydocs"), signal).await?;
// after: ensure it exists or fall back to interactive init
let path = config.read().rag_file("mydocs");
if !path.exists() {
    eprintln!("RAG 'mydocs' not found; initializing it first");
    Rag::init(&config, "mydocs", &path, &[], signal).await?;
}
config.use_rag(Some("mydocs"), signal).await?;
Defensive patterns

Strategy: validation

Validate before calling

let path = config.read().rag_file(name);
if !path.exists() && config.read().working_mode.is_cmd() {
    bail!("RAG '{name}' does not exist; initialize it in an interactive session first");
}

Try / catch

match config.use_rag(Some(name), signal).await {
    Err(e) if e.to_string().starts_with("Unknown RAG") => {
        eprintln!("No RAG named '{name}'. Available: {:?}", list_rags());
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling `use_rag(config, Some(name), abort_signal)` where `rag_file(name)` does not exist and `config.working_mode.is_cmd()` is true — e.g. a one-shot CLI invocation like `--rag mydocs` where 'mydocs' was never created.

Common situations: Typo in the RAG name in CI scripts or CLI flags; referencing a RAG created on another machine (RAG files are machine-local); running a non-interactive command before ever initializing the RAG interactively.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09). Data as JSON: /api/errors/6f42da3741dee972. Report an issue: GitHub.

Appendix: source

Thrown at src/config/mod.rs:1362

    ) -> Result<()> {
        if config.read().agent.is_some() {
            bail!("Cannot perform this operation because you are using a agent")
        }
        let rag = match rag {
            None => {
                let rag_path = config.read().rag_file(TEMP_RAG_NAME);
                if rag_path.exists() {
                    remove_file(&rag_path).with_context(|| {
                        format!("Failed to cleanup previous '{TEMP_RAG_NAME}' rag")
                    })?;
                }
                Rag::init(config, TEMP_RAG_NAME, &rag_path, &[], abort_signal).await?
            }
            Some(name) => {
                let rag_path = config.read().rag_file(name);
                if !rag_path.exists() {
                    if config.read().working_mode.is_cmd() {
                        bail!("Unknown RAG '{name}'")
                    }
                    Rag::init(config, name, &rag_path, &[], abort_signal).await?
                } else {
                    Rag::load(config, name, &rag_path)?
                }
            }
        };
        config.write().rag = Some(Arc::new(rag));
        Ok(())
    }

    pub async fn edit_rag_docs(config: &GlobalConfig, abort_signal: AbortSignal) -> Result<()> {
        let mut rag = match config.read().rag.clone() {
            Some(v) => v.as_ref().clone(),
            None => bail!("No RAG"),
        };

        let document_paths = rag.document_paths();

View on GitHub (pinned to 82976d349a)