{"record":{"id":"daa0bfefa95c357b","repo":"jdx/mise","slug":"path-raw-id-ids-may-only-contain-letters","errorCode":null,"errorMessage":"\"{path_raw}\".{id:?}: ids may only contain letters, digits, '_', '-', and '.', ignoring entry","messagePattern":"\"(.+?)\"\\.(.+?): ids may only contain letters, digits, '_', '-', and '\\.', ignoring entry","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"warning","filePath":"src/system/edits.rs","lineNumber":227,"sourceCode":"    }\n    Some((path.to_string(), id.to_string()))\n}\n\nfn resolve_entry(\n    path_raw: &str,\n    id: String,\n    entry: EditTomlEntry,\n    base: &Path,\n    config_path: &Path,\n) -> Result<EditRequest> {\n    let path = file::replace_path(path_raw);\n    if path.is_relative() {\n        bail!(\"path \\\"{path_raw}\\\" must be absolute or start with ~/, ignoring entry\");\n    }\n    // ids end up inside marker lines — keep them to characters that can't\n    // collide with the marker syntax itself\n    if id.is_empty() || !id.chars().all(|c| c.is_alphanumeric() || \"_-.\".contains(c)) {\n        bail!(\n            \"\\\"{path_raw}\\\".{id:?}: ids may only contain letters, digits, '_', '-', and '.', ignoring entry\"\n        );\n    }\n    let entry = match entry {\n        EditTomlEntry::Block(inline) => EditTomlTable {\n            block: Some(inline),\n            source: None,\n            template: None,\n            line: None,\n            comment: None,\n        },\n        EditTomlEntry::Table(table) => table,\n    };\n    let is_block = entry.block.is_some() || entry.source.is_some();\n    let op = match (&is_block, &entry.line) {\n        (true, Some(_)) => {\n            bail!(\n                \"\\\"{path_raw}\\\".{id}: block/source and line are mutually exclusive, ignoring entry\"","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/edits.rs#L209-L245","documentation":"The id is the last path segment of a [dotfiles] edit key and becomes the text inside the marker lines (# >>> mise:<id> >>>) that delimit the managed block. Ids must be non-empty and contain only alphanumerics, '_', '-', and '.' so they can never collide with the marker syntax itself. Anything else is warned about and the entry skipped.","triggerScenarios":"Keys like \"~/.zshrc/my edit\" (space), \"~/.zshrc/mise:activate\" (colon), \"~/.zshrc/#snippet\" (hash), or an id using non-ASCII characters.","commonSituations":"Natural-language ids (\"git aliases\"); copying ids from other tools that allow colons; ids with slashes that turn into extra path segments and shift the split.","solutions":["Rename the id to use only letters, digits, '_', '-', '.' — e.g. \"git-aliases\"","Check for stray spaces around the id segment in the quoted key"],"exampleFix":"# before\n[dotfiles]\n\"~/.zshrc/my edit\" = { block = 'alias ll=ls -la' }\n\n# after\n[dotfiles]\n\"~/.zshrc/my-edit\" = { block = 'alias ll=ls -la' }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn is_valid_edit_id(id: &str) -> bool {\n    !id.is_empty() && id.chars().all(|c| c.is_alphanumeric() || \"_-.\".contains(c))\n}","tryCatchPattern":null,"preventionTips":["Keep ids to lowercase-kebab or snake words (\"mise-activate\", \"git_aliases\")","Never use spaces, colons, or slashes in the id segment of the key"],"tags":["dotfiles","edits","identifier","validation"],"backgroundTag":"invalid-identifier","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}