vectordotdev/vector · error

invalid slug ' ': only ASCII letters, digits, '_', and '-'…

Error message

invalid slug '{slug}': only ASCII letters, digits, '_', and '-' are allowed (got a path separator or punctuation?)

What it means

`validate_slug` requires slugs to consist only of ASCII alphanumerics, `_`, and `-`. Slugs become part of the fragment filename, so path separators or other punctuation are rejected to keep the file a single safe component under changelog.d/.

Solutions

  1. Re-run with a slug containing only [A-Za-z0-9_-], e.g. `my-fix-123`
  2. Strip/replace offending characters yourself: `slug=$(printf '%s' "$raw" | tr -c 'A-Za-z0-9_' '-')`
  3. For unsafe/programmatic input, validate the slug in the caller before invoking

Example fix

// before
vdev changelog new bug_fix "my fix!!"
// after
vdev changelog new bug_fix "my-fix"
Defensive patterns

Strategy: validation

Validate before calling

if (!/^[A-Za-z0-9_-]+$/.test(slug)) throw new Error(`invalid slug '${slug}'`);

Type guard

const isValidSlug = (s) => typeof s === "string" && /^[A-Za-z0-9_-]+$/.test(s);

Try / catch

try { runVdevNew(type, raw); } catch (e) { if (/invalid slug/.test(e.message)) runVdevNew(type, raw.replace(/[^A-Za-z0-9_-]/g, "-")); else throw e; }

Prevention

When it happens

Trigger: Calling `vdev changelog new <type> <slug>` where the slug contains `/`, `\`, spaces, dots, or other punctuation — including accidental absolute paths (`/tmp/foo`) or `..`.

Common situations: Pasting a path or sentence fragment as a slug; forgetting to replace spaces/hyphens-in-titles; shell quoting issues leaving slashes in the argument; untrusted input passed straight to the CLI.

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 vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/37df4c0925f78d23. Report an issue: GitHub.

Appendix: source

Thrown at vdev/src/commands/changelog/new.rs:84

        }

        info!("Created {}", relative(&repo_root, &file).display());
        info!("Edit the file, then run `vdev check changelog-fragments` to validate.");
        Ok(())
    }
}

/// A slug must be one filename component: ASCII alnum, `_`, or `-` only.
/// Rejects path separators, `..`, absolute paths, and anything with punctuation.
fn validate_slug(slug: &str) -> Result<()> {
    if slug.is_empty() {
        bail!("slug must not be empty");
    }
    if !slug
        .chars()
        .all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
    {
        bail!(
            "invalid slug '{slug}': only ASCII letters, digits, '_', and '-' are allowed (got a path separator or punctuation?)"
        );
    }
    Ok(())
}

fn render_template(fragment_type: &FragmentType, author: &str) -> String {
    if fragment_type.breaking {
        formatdoc! {"
            # TODO one-line title

            ## Summary

            TODO one-paragraph summary that lands in the release changelog list.

            ## Migration

            TODO how to migrate. Use `N/A` for informational-only breakers.

View on GitHub (pinned to bdb87aeaa4)