espanso/espanso · error
unable to parse search configuration
Error message
unable to parse search configuration
What it means
When the `--json` flag is present, search_main parses the input data with serde_json::from_str into a config::SearchConfig; a parse/type mismatch panics via this .expect(). It means the JSON input is not syntactically valid JSON or does not match the expected SearchConfig schema (e.g. missing or wrongly-typed fields like `items`).
Source
Thrown at espanso/src/cli/modulo/search.rs:43
pub fn search_main(matches: &ArgMatches, icon_paths: &IconPaths) -> i32 {
let as_json: bool = matches.is_present("json");
let input_file = matches
.value_of("input_file")
.expect("missing input, please specify the -i option");
let data = if input_file == "-" {
use std::io::Read;
let mut buffer = String::new();
std::io::stdin()
.read_to_string(&mut buffer)
.expect("unable to obtain input from stdin");
buffer
} else {
std::fs::read_to_string(input_file).expect("unable to read input file")
};
let mut config: config::SearchConfig = if as_json {
serde_json::from_str(&data).expect("unable to parse search configuration")
} else {
serde_norway::from_str(&data).expect("unable to parse search configuration")
};
// Overwrite the icon
config.icon = icon_paths
.logo
.as_deref()
.map(|path| path.to_string_lossy().to_string());
let algorithm = algorithm::get_algorithm(&config.algorithm, true);
let search = generator::generate(config);
let result = show(search, algorithm);
let mut result_map = HashMap::new();
result_map.insert("selected", result);
let output = serde_json::to_string(&result_map).expect("unable to encode values as JSON");View on GitHub (pinned to e6c3736675)
Solutions
- Validate the JSON file with a linter (e.g. `jq . input.json`) to catch syntax errors
- Compare the input structure against config::SearchConfig fields (items, hint, etc.) and fix types/required fields
- Do not pass --json when the input is YAML; use the default YAML path instead
- If generating JSON programmatically, print/inspect the payload before handing it to modulo search
Example fix
// before
{"items": [{"id": 1, "label": "x",}} // trailing comma
// after
{"items": [{"id": "1", "label": "x"}]} Defensive patterns
Strategy: validation
Validate before calling
jq -e . input.json > /dev/null || { echo 'invalid JSON' >&2; exit 2; }
jq -e 'has("items") and (.items | type == "array")' input.json
espanso modulo search -i input.json --json Type guard
fn is_valid_search_json(s: &str) -> bool {
serde_json::from_str::<serde_json::Value>(s)
.ok()
.map(|v| v.get("items").map_or(false, |i| i.is_array()))
.unwrap_or(false)
} Try / catch
let config = match serde_json::from_str::<config::SearchConfig>(&data) {
Ok(c) => c,
Err(e) => { eprintln!("unable to parse search configuration: {e}"); return 1; }
}; Prevention
- Run the JSON through jq or a linter before passing --json
- Keep item objects aligned with config::SearchConfig fields (id, label)
- Never feed YAML/other formats with --json set
When it happens
Trigger: Running `espanso modulo search -i <file> --json` where the file contains malformed JSON, or valid JSON whose structure does not deserialize into config::SearchConfig.
Common situations: Hand-editing the JSON input and breaking syntax (trailing commas, unquoted keys); producing the file from a tool that emits a different JSON shape than SearchConfig expects; feeding a YAML file to --json by mistake.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unable to encode values as JSON
- unable to read preference for key {key}
- unable to load icon paths
- missing input, please specify the -i option
- unable to obtain input from stdin
AI-assisted analysis of espanso/espanso@e6c3736675 (2026-09-06).
Data as JSON: /api/errors/c631ffc75864b1f2.
Report an issue: GitHub.