jdx/mise · error
expected EnvironmentVariables dictionary, got {value:?}
Error message
expected EnvironmentVariables dictionary, got {value:?} What it means
Test assertion panic in test_render_plist. The test requires that the plist dictionary rendered by render_plist contains an 'EnvironmentVariables' key holding a dictionary in which PATH equals /usr/bin:/bin. The panic arm runs whenever the key is absent or holds a non-dictionary value, dumping the actual value with {:?}.
Source
Thrown at src/system/launchd.rs:818
.to_string_lossy()
.to_string()
))
);
match dict.get("ProgramArguments") {
Some(Value::Array(args)) => {
assert_eq!(args[0], Value::String("/bin/echo".to_string()));
assert_eq!(args[1], Value::String("hello".to_string()));
}
value => panic!("expected ProgramArguments array, got {value:?}"),
}
match dict.get("EnvironmentVariables") {
Some(Value::Dictionary(env)) => {
assert_eq!(
env.get("PATH"),
Some(&Value::String("/usr/bin:/bin".to_string()))
);
}
value => panic!("expected EnvironmentVariables dictionary, got {value:?}"),
}
assert!(plist_matches(&plist, &request));
}
#[test]
fn test_render_plist_multiple_calendar_intervals() {
let request = LaunchdRequest {
name: "sync".to_string(),
label: "dev.mise.sync".to_string(),
program: "/bin/echo".to_string(),
args: vec![],
run_at_load: false,
keep_alive: false,
keep_alive_on_failure: false,
start_interval: None,
throttle_interval: None,
nice: None,
start_calendar_interval: Some(LaunchdCalendarIntervals::Multiple(vec![View on GitHub (pinned to afd2eddd3a)
Solutions
- Inspect the {value:?} payload in the panic to see the actual parsed plist fragment
- Check render_plist in src/system/launchd.rs still serializes request.environment as an 'EnvironmentVariables' dictionary
- Restore the key or update the test to match the new intended plist schema
- Verify the PATH entry survives any env filtering/normalization added to render_plist
Example fix
// before
value => panic!("expected EnvironmentVariables dictionary, got {value:?}"),
// after
// ensure render_plist emits:
// "EnvironmentVariables" => Value::Dictionary(map with "PATH" => Value::String("/usr/bin:/bin")) Defensive patterns
Strategy: validation
Validate before calling
let env = match dict.get("EnvironmentVariables") {
Some(Value::Dictionary(e)) => e,
other => panic!("EnvironmentVariables missing or wrong type: {other:?}"),
};
assert_eq!(env.get("PATH"), Some(&Value::String("/usr/bin:/bin".into()))); Type guard
fn as_dict(v: Option<&Value>) -> Option<&std::collections::HashMap<String, Value>> {
match v { Some(Value::Dictionary(d)) => Some(d), _ => None }
} Prevention
- Never serialize empty env maps by omitting the key if tests expect the key present
- Cover env serialization in a focused unit test on render_plist
- Keep key names as constants shared between serializer and tests
When it happens
Trigger: render_plist omits 'EnvironmentVariables' from the generated launchd plist, or emits it as a non-dictionary (array/string), so the match on dict.get("EnvironmentVariables") falls through to the catch-all arm.
Common situations: Refactoring how environment variables are serialized into the plist, accidentally skipping empty env maps, or renaming the key — all cause this test to panic during cargo test.
Related errors
- expected dictionary, got {value:?}
- expected StartCalendarInterval dictionary, got {value:?}
- expected ProgramArguments array, got {value:?}
- expected first calendar interval dictionary, got {value:?}
- expected second calendar interval dictionary, got {value:?}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/917badfcc6b96440.
Report an issue: GitHub.