sigoden/aichat · error · anyhow::Error
. Usage
Error message
{err}. Usage: {} What it means
In src/config/mod.rs macro-argument handling, `macro_value.resolve_variables(&new_args)` failed while expanding `$1`-style variables in macro arguments. The library wraps the underlying error with the macro's usage string: `{err}. Usage: {}` so the caller sees how to invoke it correctly.
Solutions
- Follow the printed `Usage:` line exactly — it shows required arguments/variables.
- Quote arguments containing spaces: `llm --macro summarize "long text here"`.
- Check the macro definition (`$1`, `$2`, flags) and supply every declared variable.
- On Windows, mind path backslash/quote handling if the macro expects raw text.
Example fix
// before llm --macro translate Error: missing variable $1. Usage: translate <text> // after llm --macro translate "hello world"
Defensive patterns
Strategy: validation
Validate before calling
// Shell: check argument count against macro usage before invoking
usage=$(llm --macro mymacro 2>&1 | sed -n 's/.*Usage: //p')
[[ $# -ge 1 ]] || { echo "Usage: $usage"; exit 1; } Try / catch
// Rust
match run_macro(name, args) {
Err(e) if e.to_string().contains("Usage:") => {
eprintln!("{e}"); // usage message is embedded — surface it verbatim
}
other => other?,
} Prevention
- Quote all arguments containing spaces.
- Read the macro's declared variables ($1, $2, flags) before invoking.
- Count supplied arguments against the usage line.
- Be aware of Windows arg-splitting differences.
When it happens
Trigger: Running a macro with arguments that don't satisfy its declared variables (missing required positional args, invalid flag syntax, or text split issues) — resolve_variables returns Err and it's mapped to include `macro_value.usage(name)`.
Common situations: Invoking `llm --macro NAME` with too few arguments; forgetting to quote an argument containing spaces; Windows argument-splitting quirks with `split_args_text`.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09).
Data as JSON: /api/errors/9ae9acea99125e1b.
Report an issue: GitHub.
Appendix: source
Thrown at src/config/mod.rs:2474
*self == WorkingMode::Serve
}
}
#[async_recursion::async_recursion]
pub async fn macro_execute(
config: &GlobalConfig,
name: &str,
args: Option<&str>,
abort_signal: AbortSignal,
) -> Result<()> {
let macro_value = Config::load_macro(name)?;
let (mut new_args, text) = split_args_text(args.unwrap_or_default(), cfg!(windows));
if !text.is_empty() {
new_args.push(text.to_string());
}
let variables = macro_value
.resolve_variables(&new_args)
.map_err(|err| anyhow!("{err}. Usage: {}", macro_value.usage(name)))?;
let role = config.read().extract_role();
let mut config = config.read().clone();
config.temperature = role.temperature();
config.top_p = role.top_p();
config.use_tools = role.use_tools().clone();
config.macro_flag = true;
config.model = role.model().clone();
config.role = None;
config.session = None;
config.rag = None;
config.agent = None;
config.discontinuous_last_message();
let config = Arc::new(RwLock::new(config));
config.write().macro_flag = true;
for step in ¯o_value.steps {
let command = Macro::interpolate_command(step, &variables);
println!(">> {}", multiline_text(&command));
run_repl_command(&config, abort_signal.clone(), &command).await?;View on GitHub (pinned to 82976d349a)