{"record":{"id":"37df4c0925f78d23","repo":"vectordotdev/vector","slug":"invalid-slug-slug-only-ascii-letters-digits-and-are-allowed","errorCode":null,"errorMessage":"invalid slug '{slug}': only ASCII letters, digits, '_', and '-' are allowed (got a path separator or punctuation?)","messagePattern":"invalid slug '(.+?)': only ASCII letters, digits, '_', and '-' are allowed \\(got a path separator or punctuation\\?\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vdev/src/commands/changelog/new.rs","lineNumber":84,"sourceCode":"        }\n\n        info!(\"Created {}\", relative(&repo_root, &file).display());\n        info!(\"Edit the file, then run `vdev check changelog-fragments` to validate.\");\n        Ok(())\n    }\n}\n\n/// A slug must be one filename component: ASCII alnum, `_`, or `-` only.\n/// Rejects path separators, `..`, absolute paths, and anything with punctuation.\nfn validate_slug(slug: &str) -> Result<()> {\n    if slug.is_empty() {\n        bail!(\"slug must not be empty\");\n    }\n    if !slug\n        .chars()\n        .all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')\n    {\n        bail!(\n            \"invalid slug '{slug}': only ASCII letters, digits, '_', and '-' are allowed (got a path separator or punctuation?)\"\n        );\n    }\n    Ok(())\n}\n\nfn render_template(fragment_type: &FragmentType, author: &str) -> String {\n    if fragment_type.breaking {\n        formatdoc! {\"\n            # TODO one-line title\n\n            ## Summary\n\n            TODO one-paragraph summary that lands in the release changelog list.\n\n            ## Migration\n\n            TODO how to migrate. Use `N/A` for informational-only breakers.","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/vdev/src/commands/changelog/new.rs#L66-L102","documentation":"`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/.","triggerScenarios":"Calling `vdev changelog new <type> <slug>` where the slug contains `/`, `\\`, spaces, dots, or other punctuation — including accidental absolute paths (`/tmp/foo`) or `..`.","commonSituations":"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.","solutions":["Re-run with a slug containing only [A-Za-z0-9_-], e.g. `my-fix-123`","Strip/replace offending characters yourself: `slug=$(printf '%s' \"$raw\" | tr -c 'A-Za-z0-9_' '-')`","For unsafe/programmatic input, validate the slug in the caller before invoking"],"exampleFix":"// before\nvdev changelog new bug_fix \"my fix!!\"\n// after\nvdev changelog new bug_fix \"my-fix\"","handlingStrategy":"validation","validationCode":"if (!/^[A-Za-z0-9_-]+$/.test(slug)) throw new Error(`invalid slug '${slug}'`);","typeGuard":"const isValidSlug = (s) => typeof s === \"string\" && /^[A-Za-z0-9_-]+$/.test(s);","tryCatchPattern":"try { runVdevNew(type, raw); } catch (e) { if (/invalid slug/.test(e.message)) runVdevNew(type, raw.replace(/[^A-Za-z0-9_-]/g, \"-\")); else throw e; }","preventionTips":["Normalize titles to kebab-case before passing as slugs","Never pass paths or free text as the slug argument","Validate untrusted input before exec-ing the CLI"],"tags":["cli","validation","filename"],"backgroundTag":"invalid-identifier-format","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}