{"record":{"id":"4c4b7a34ec4208a0","repo":"helix-editor/helix","slug":"err","errorCode":null,"errorMessage":"{err}","messagePattern":"\\{err\\}","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"helix-view/src/expansion.rs","lineNumber":224,"sourceCode":"    let mut start = 0;\n\n    while let Some(offset) = content[start..].find('%') {\n        let idx = start + offset;\n        if content.as_bytes().get(idx + '%'.len_utf8()).copied() == Some(b'%') {\n            // Treat two percents in a row as an escaped percent.\n            escaped.push_str(&content[start..=idx]);\n            // Skip over both percents.\n            start = idx + ('%'.len_utf8() * 2);\n        } else {\n            // Otherwise interpret the percent as an expansion. Push up to (but not\n            // including) the percent token.\n            escaped.push_str(&content[start..idx]);\n            // Then parse the expansion,\n            let mut tokenizer = Tokenizer::new(&content[idx..], true);\n            let token = tokenizer\n                .parse_percent_token()\n                .unwrap()\n                .map_err(|err| anyhow!(\"{err}\"))?;\n            // expand it (this is the recursive part),\n            let expanded = expand(editor, token)?;\n            escaped.push_str(expanded.as_ref());\n            // and move forward to the end of the expansion.\n            start = idx + tokenizer.pos();\n        }\n    }\n\n    if escaped.is_empty() {\n        Ok(content)\n    } else {\n        escaped.push_str(&content[start..]);\n        Ok(Cow::Owned(escaped))\n    }\n}\n\n// Note: the lifetime of the expanded variable (the `Cow`) must not be tied to the lifetime of\n// the borrow of `Editor`. That would prevent commands from mutating the `Editor` until the","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/helix-editor/helix/blob/079a789e8cb08ead67f19e1971a1b7438b37354b/helix-view/src/expansion.rs#L206-L242","documentation":"expand_inner recursively expands percent tokens inside a %( ... ) / expand-style token. When the inner tokenizer's parse_percent_token fails, the ParseArgsError is wrapped with anyhow!(\"{err}\") — the most common inner error being \"'%' was not properly escaped. Please use '%%'\". So this error is a re-surface of a tokenizer failure for malformed percent syntax inside the expansion.","triggerScenarios":"A single unescaped % inside an expand token's content, an unterminated %{...} or %u{...}, or any percent construct the tokenizer cannot parse at that position — all while command-line validation is enabled so the name token cannot be the culprit.","commonSituations":"Building format strings that contain literal percent signs (date formats, printf-style templates) without doubling them; nested expansions where an inner %u{...} is missing its closing brace.","solutions":["Escape every literal % as %% inside the expanded content.","Check that all %{...} and %u{...} groups are closed with '}'.","Re-run with the inner content simplified to isolate which percent token fails to parse."],"exampleFix":"# before\n :echo %(echo \"100% done\")\n\n# after\n :echo %(echo \"100%% done\")","handlingStrategy":"try-catch","validationCode":"use helix_core::command_line::Tokenizer;\n\n// dry-run: every '%' inside content must parse or be doubled\nfn percent_syntax_ok(content: &str) -> bool {\n    let mut t = Tokenizer::new(content, true);\n    loop {\n        match t.next() {\n            None | Some(Ok(_)) if t.pos() >= content.len() => return true,\n            Some(Err(_)) => return false,\n            _ => continue,\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"let expanded = expand_inner(editor, content).map_err(|err| {\n    anyhow!(\"expansion of '{content}' failed: {err:#}\") // inner err is terse; add the payload\n})?;","preventionTips":["Double every literal % as %% inside expandable content.","Close all %{...} / %u{...} groups.","Dry-run the tokenizer over user-built strings before expanding them."],"tags":["expansion","escaping","command-line","helix","rust"],"backgroundTag":null,"analyzedSha":"079a789e8cb08ead67f19e1971a1b7438b37354b","analyzedAt":"2026-08-16T09:09:59.668Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}