BoundaryML/baml · error

' ' contains an

Error message

'{}' contains an {e}

What it means

After the org slug validates, ProjectFqn::parse validates the project shortname via is_valid_project_shortname and, on failure, wraps the inner error as "'{fqn}' contains an {e}". The inner error (e) describes the specific shortname rule violated (length, charset, etc.).

Solutions

  1. Read the wrapped inner error ({e}) to see which shortname rule failed and fix the shortname accordingly
  2. Ensure the shortname is non-empty and uses allowed characters per is_valid_project_shortname
  3. Trim separators/whitespace before parsing
  4. Add pre-parse validation in the CLI to give users a friendly message

Example fix

// before
let fqn = ProjectFqn::parse("my-org/")?; // empty shortname
// after
let fqn = ProjectFqn::parse("my-org/my-project")?;
Defensive patterns

Strategy: validation

Validate before calling

fn valid_shortname(s: &str) -> bool { !s.is_empty() && s.len() <= 64 && s.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_') }

Try / catch

match ProjectFqn::parse(input) { Ok(f) => f, Err(e) => { eprintln!("invalid FQN: {e}"); return Ok(()); } }

Prevention

When it happens

Trigger: Calling ProjectFqn::parse with an FQN whose project segment fails is_valid_project_shortname — e.g. invalid characters, wrong length, or empty shortname after the separator.

Common situations: Constructing FQNs from unvalidated user input or file paths; renames that leave trailing separators like "org/" producing an empty shortname.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at engine/bstd/src/project_fqn.rs:58

        }
    }

    pub fn parse(fqn: impl AsRef<str>) -> Result<Self> {
        let fqn = fqn.as_ref();
        let (org_slug, project_shortname) = fqn.split_once('/').context(format!(
            "'{fqn}' is not a valid fully-qualified project name - must specify both an org and project name"
        ))?;
        let org_slug = org_slug.to_string();
        let project_shortname = project_shortname.to_string();

        let org_slug_regex = Regex::new(r"^[a-z0-9_][a-z0-9_-]*$")
            .context("Failed to construct org name validator")?;

        if !org_slug_regex.is_match(&org_slug) {
            anyhow::bail!("'{}' contains an invalid org name ('{}')", fqn, org_slug);
        }
        Self::is_valid_project_shortname(&project_shortname)
            .map_err(|e| anyhow::anyhow!("'{}' contains an {e}", fqn))?;
        Ok(Self {
            org_slug,
            project_shortname,
        })
    }
}

impl Display for ProjectFqn {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}/{}", self.org_slug, self.project_shortname)
    }
}

#[cfg(test)]
mod tests {
    use pretty_assertions::assert_eq;

    use super::*;

View on GitHub (pinned to bd85ce9dee)