sigoden/aichat · error · anyhow::Error

Invalid document path

Error message

Invalid document path: '{path}'

What it means

In src/config/agent.rs `init`, each document path from an agent definition is either a URL (kept as-is) or joined with the agent's `functions_dir` via `safe_join_path`. When the join fails — the path is unsafe (e.g. absolute or escaping the functions dir) — the library throws `Invalid document path: '{path}'` rather than resolving a path outside the allowed directory.

Solutions

  1. Use a path relative to the agent's functions directory (e.g. `docs/manual.md`).
  2. If the document is remote, pass a proper URL (`https://...`) so the is_url branch accepts it.
  3. Remove any absolute path or `..` traversal from the documents list.
  4. Move the document file into the functions directory and reference it by relative name.

Example fix

// before (config.yaml)
documents:
  - /home/me/notes/spec.md

// after
documents:
  - spec.md   # file placed inside the agent's functions dir
Defensive patterns

Strategy: validation

Validate before calling

// Rust
fn valid_doc_path(p: &str, functions_dir: &Path) -> bool {
    p.starts_with("http://") || p.starts_with("https://")
        || safe_join_path(functions_dir, std::path::Path::new(p)).is_some()
}

Type guard

fn is_url(s: &str) -> bool { s.starts_with("http://") || s.starts_with("https://") }

Prevention

When it happens

Trigger: An agent definition lists a `documents` entry that is not a URL and cannot be safely joined with functions_dir: absolute paths like `/etc/passwd`, `../` traversal outside the functions dir, or empty/odd path segments.

Common situations: Copying an agent config from another machine with absolute document paths; accidentally writing `../..` in a document entry; symlinks or path normalization surprises.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


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

Appendix: source

Thrown at src/config/agent.rs:93

        };

        let rag = if rag_path.exists() {
            Some(Arc::new(Rag::load(config, DEFAULT_AGENT_NAME, &rag_path)?))
        } else if !definition.documents.is_empty() && !config.read().info_flag {
            let mut ans = false;
            if *IS_STDOUT_TERMINAL {
                ans = Confirm::new("The agent has the documents, init RAG?")
                    .with_default(true)
                    .prompt()?;
            }
            if ans {
                let mut document_paths = vec![];
                for path in &definition.documents {
                    if is_url(path) {
                        document_paths.push(path.to_string());
                    } else {
                        let new_path = safe_join_path(&functions_dir, path)
                            .ok_or_else(|| anyhow!("Invalid document path: '{path}'"))?;
                        document_paths.push(new_path.display().to_string())
                    }
                }
                let rag =
                    Rag::init(config, "rag", &rag_path, &document_paths, abort_signal).await?;
                Some(Arc::new(rag))
            } else {
                None
            }
        } else {
            None
        };

        Ok(Self {
            name: name.to_string(),
            config: agent_config,
            definition,
            shared_variables: Default::default(),

View on GitHub (pinned to 82976d349a)