BoundaryML/baml · error · SourceRootError

a source root already exists at this path

Error message

a source root already exists at this path

What it means

SourceRootError::PathTaken is returned by ProjectDatabase::add_source_root (and add_dependency paths) when a live source root already sits at the same canonical path. The DB refuses to register a duplicate root so each file belongs to exactly one package; the error carries the existing SourceRoot.

Source

Thrown at baml_language/crates/baml_db/src/db.rs:86

    #[must_use]
    pub fn served_from(mut self, interface: Vec<u8>) -> Self {
        self.interface = Some(interface);
        self
    }

    #[must_use]
    pub fn depending_on(mut self, dependencies: Vec<Dependency>) -> Self {
        self.dependencies = dependencies;
        self
    }
}

/// Why [`ProjectDatabase::add_source_root`] or
/// [`ProjectDatabase::add_dependency`] refused.
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum SourceRootError {
    /// A live root already sits at this (canonical) path.
    #[error("a source root already exists at this path")]
    PathTaken(SourceRoot),
    /// The edge name is one no package may declare: a stdlib package's name
    /// (already an implicit edge of every package) or a source-level
    /// qualifier (`root`, `env`).
    #[error("dependency name `{name}` is reserved")]
    ReservedDependencyName { name: Name },
    /// The root already has an edge under this name.
    #[error("dependency `{name}` is declared twice")]
    DuplicateDependencyName { name: Name },
    /// The edge names a root that is not live in this database.
    #[error("dependency `{name}` names a source root that does not exist")]
    UnknownDependencyRoot { name: Name },
    /// The edge would make the dependency graph cyclic.
    #[error("dependency `{name}` would form a dependency cycle")]
    DependencyCycle { name: Name },
    /// The interface bytes are not a valid `PackageInterface` artifact.
    #[error("invalid package interface: {message}")]
    InvalidInterface { message: String },

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Check whether the path is already registered (e.g. keep a set of canonical roots) and skip the duplicate add_source_root call.
  2. Canonicalize your paths (std::fs::canonicalize) before comparing, and dedupe symlinks/relative forms.
  3. Match on SourceRootError::PathTaken and treat it as a no-op if re-registration is expected in your tooling.
  4. If you truly need a fresh database, rebuild the ProjectDatabase instead of re-adding roots to the existing one.

Example fix

// before
db.add_source_root(path).unwrap();
// after
match db.add_source_root(&path) {
    Ok(()) => {},
    Err(SourceRootError::PathTaken(existing)) if existing.path() == path => {}, // already registered
    Err(e) => return Err(e.into()),
}
Defensive patterns

Strategy: validation

Validate before calling

let canonical = std::fs::canonicalize(&path)?;
if registered_roots.contains(&canonical) {
    // skip add_source_root
}

Try / catch

match db.add_source_root(&path) {
    Ok(()) => {},
    Err(SourceRootError::PathTaken(_)) => { /* already registered: treat as no-op */ }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling add_source_root with a path that canonicalizes to a root already added (including via symlinks or relative paths like ./src vs an absolute /abs/src), or re-adding the same root twice in one session.

Common situations: Configuring the same directory twice (once relative, once absolute or through a symlink); adding a dependency root that overlaps a project root; hot-reload logic re-registering roots without checking existing ones.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/6f09303e799a4689. Report an issue: GitHub.