jdx/mise · error

invalid compose project_name

Error message

invalid compose project_name '{name}': use lowercase letters, digits, dashes, and underscores

What it means

Compose project names must follow Docker's naming rules; this validator requires a non-empty name starting with a lowercase ASCII letter or digit and containing only lowercase letters, digits, dashes, and underscores. Any other name is rejected before it reaches compose.

Solutions

  1. Rename the project using only [a-z0-9_-] and ensure the first character is a lowercase letter or digit
  2. Replace invalid characters (e.g. spaces, dots, uppercase) with dashes or underscores
  3. Let the tool derive the name from a compliant directory name instead of overriding it

Example fix

// before
project_name = "My Project.v2"
// after
project_name = "my-project-v2"
Defensive patterns

Strategy: validation

Validate before calling

fn valid_project_name(name: &str) -> bool {
    !name.is_empty()
        && name.chars().next().map(|c| c.is_ascii_lowercase() || c.is_ascii_digit()).unwrap_or(false)
        && name.chars().all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-' || c == '_')
}

Prevention

When it happens

Trigger: Setting `project_name` in a compose-based config with uppercase letters, spaces, dots, slashes, or a leading dash/underscore/digit-less start.

Common situations: Using a directory name containing uppercase or dots as the project name, copy-pasting a name with spaces, or deriving the name from a path.

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 jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/f36c6d5f21f8cc51. Report an issue: GitHub.

Appendix: source

Thrown at src/system/compose.rs:1126

    Ok(std::iter::once(resolved.to_string_lossy().to_string())
        .chain(args.iter().cloned())
        .collect())
}

fn validate_project_name(name: Option<&str>) -> Result<()> {
    let Some(name) = name else {
        return Ok(());
    };
    if name.is_empty()
        || !name
            .chars()
            .next()
            .is_some_and(|character| character.is_ascii_lowercase() || character.is_ascii_digit())
        || !name.chars().all(|character| {
            character.is_ascii_lowercase() || character.is_ascii_digit() || "-_".contains(character)
        })
    {
        bail!(
            "invalid compose project_name '{name}': use lowercase letters, digits, dashes, and underscores"
        );
    }
    Ok(())
}

fn parse_dependency(value: &str) -> Result<ResourceId> {
    let Some((kind, name)) = value.split_once(':') else {
        bail!("invalid compose dependency '{value}': expected '<kind>:<name>'");
    };
    if name.is_empty()
        || !matches!(
            kind,
            "package" | "file" | "directory" | "service" | "user" | "group"
        )
    {
        bail!(
            "invalid compose dependency '{value}': supported kinds are package, file, directory, service, user, and group"

View on GitHub (pinned to 533346cc37)