jdx/mise · error · eyre::Report
task {task_name} input group cycle: {}
Error message
task {task_name} input group cycle: {} What it means
Thrown while mise expands task `inputs` entries that reference input groups (`@group:<name>`) in mise.toml. `expand_task_inputs` (src/config/mod.rs:2961) keeps a stack of group names currently being expanded; if the same group appears again deeper in the chain (a -> b -> a), expansion could never terminate, so mise bails and prints the full cycle path. This is task-configuration validation, not a failure of the task itself.
Source
Thrown at src/config/mod.rs:2988
for entry in entries {
let Some(group) = entry.strip_prefix(TASK_INPUT_GROUP_PREFIX) else {
expanded.push(if anchor_literals {
anchor_task_input(root, entry)
} else {
entry.clone()
});
continue;
};
let (groups, groups_root) = task_inputs.input_groups.as_ref().ok_or_else(|| {
eyre!("task {task_name} references undefined input group {group:?} with {entry:?}")
})?;
let inputs = groups.get(group).ok_or_else(|| {
eyre!("task {task_name} references undefined input group {group:?} with {entry:?}")
})?;
if let Some(cycle_start) = stack.iter().position(|name| name == group) {
let mut cycle = stack[cycle_start..].to_vec();
cycle.push(group.to_string());
bail!(
"task {task_name} input group cycle: {}",
cycle.iter().join(" -> ")
);
}
stack.push(group.to_string());
expanded.extend(expand_task_inputs(
inputs,
task_inputs,
groups_root,
task_name,
stack,
true,
)?);
stack.pop();
}
Ok(expanded)
}
View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Read the cycle in the message (e.g. `a -> b -> a`) and open the `[task_inputs.groups.*]` definitions in the config file being loaded
- Break the loop by removing the `@group:` reference that closes it (the edge back to the first group in the printed cycle)
- If two groups must share content, extract a third base group and have both include it instead of each other
- Re-run any task-loading command (e.g. `mise tasks ls`) to confirm the config now parses
Example fix
# before — cycle: shared -> lint -> shared [task_inputs.groups.shared] inputs = ["src/**", "@group:lint"] [task_inputs.groups.lint] inputs = ["@group:shared", "lint/**"] # after — one-directional references only [task_inputs.groups.base] inputs = ["src/**"] [task_inputs.groups.shared] inputs = ["@group:base"] [task_inputs.groups.lint] inputs = ["@group:base", "lint/**"]
Defensive patterns
Strategy: validation
Validate before calling
# pre-commit lint: fail on input-group cycles before mise does
import tomllib, sys
cfg = tomllib.load(open("mise.toml", "rb"))
groups = cfg.get("task_inputs", {}).get("groups", {})
def dfs(g, stack):
if g in stack:
sys.exit(f"input group cycle: {' -> '.join(stack[stack.index(g):] + [g])}")
for ref in groups.get(g, []):
if isinstance(ref, str) and ref.removeprefix("@group:") in groups:
dfs(ref.removeprefix("@group:"), stack + [g])
for g in groups:
dfs(g, []) Prevention
- Keep group references one-directional: define 'base' groups that others include, never mutual includes
- Run `mise tasks ls` (or any task-loading command) in CI so cycle typos fail the build early
- When renaming a group, grep for `@group:<old-name>` across all config files before committing
When it happens
Trigger: A task's `inputs` (or a group's member list) contains `@group:a`, group `a` includes `@group:b`, and group `b` includes `@group:a` again — directly or through more groups. The error fires only when a group name is already on the expansion stack; referencing a group once, or referencing it from two sibling groups, is fine.
Common situations: Refactoring shared input lists into groups and accidentally making two groups reference each other; renaming a group so an old name now resolves into a chain that loops back; copy-pasting a group definition and leaving a self/mutual reference; YAML anchors duplicating group references.
Related errors
- task includes do not contain an existing directory where a f
- config file not found: {}
- No mise.toml file found
- No mise.toml file found
- config file not found: {}
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/1b8a2d4969f77979.
Report an issue: GitHub.