{"record":{"id":"0f9546df78ceff89","repo":"jdx/mise","slug":"mas-list-json-returned-an-app-object-without-an","errorCode":null,"errorMessage":"mas list --json returned an app object without an ID and version","messagePattern":"mas list --json returned an app object without an ID and version","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/mas.rs","lineNumber":115,"sourceCode":"    }\n    if let Ok(Value::Array(values)) = serde_json::from_str::<Value>(output) {\n        let apps: Vec<_> = values.iter().filter_map(parse_mas_json_value).collect();\n        if apps.is_empty() && !values.is_empty() {\n            bail!(\"mas list --json returned no parseable app objects\");\n        }\n        return Ok(apps);\n    }\n    let mut apps = vec![];\n    for line in output\n        .lines()\n        .map(str::trim)\n        .filter(|line| !line.is_empty())\n    {\n        let value = serde_json::from_str::<Value>(line)\n            .map_err(|err| eyre!(\"mas list --json returned invalid JSON: {err}\"))?;\n        match parse_mas_json_value(&value) {\n            Some(app) => apps.push(app),\n            None => bail!(\"mas list --json returned an app object without an ID and version\"),\n        }\n    }\n    Ok(apps)\n}\n\nfn parse_mas_text(output: &str) -> Vec<InstalledApp> {\n    output\n        .lines()\n        .filter_map(|line| {\n            let (adam_id, rest) = line.trim().split_once(char::is_whitespace)?;\n            if !adam_id.chars().all(|c| c.is_ascii_digit()) {\n                return None;\n            }\n            let version = rest\n                .rsplit_once('(')\n                .and_then(|(_, v)| v.strip_suffix(')'))\n                .unwrap_or(\"\")\n                .trim();","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/packages/mas.rs#L97-L133","documentation":"parse_mas_json parses newline-delimited JSON output of `mas list --json`. Every line must be a JSON object carrying both an app ID and a version; parse_mas_json_value returns None when either field is missing or not usable, and the parser aborts with this error rather than silently dropping the app.","triggerScenarios":"`mas list --json` emits a line that parses as JSON but lacks the ID or version field (or they are of an unexpected type), so parse_mas_json_value returns None. Also triggered by a mas version whose --json schema differs from the expected shape.","commonSituations":"A mas CLI update changed its JSON output schema; an oddly reported App Store app missing metadata fields; running a very old or unofficial mas build; non-mas tool on PATH named mas emitting unrelated JSON per line.","solutions":["Check `mas version` and upgrade mas to a current release so `--json` output matches the expected schema","Run `mas list --json` manually and inspect which line/object is missing the id or version field","Update mise to a version whose parse_mas_json_value understands the mas JSON schema in use","Work around by letting mise use `mas list` text output (remove/adjust json preference) if available"],"exampleFix":"// before\nNone => bail!(\"mas list --json returned an app object without an ID and version\")\n// after: tolerate the line and log instead of failing the whole listing\nmatch parse_mas_json_value(&value) {\n    Some(app) => apps.push(app),\n    None => {\n        debug!(\"skipping mas json line without id/version: {value}\");\n    }\n}","handlingStrategy":"validation","validationCode":"fn looks_like_mas_app(v: &serde_json::Value) -> bool {\n    v.get(\"id\").map_or(false, |i| i.is_number() || i.is_string())\n        && v.get(\"version\").map_or(false, |x| x.is_string() || x.is_number())\n}","typeGuard":"fn is_app_with_id_and_version(v: &Value) -> Option<(&Value, &Value)> {\n    Some((v.get(\"id\")?, v.get(\"version\")?))\n}","tryCatchPattern":"match parse_mas_json_value(&value) {\n    Some(app) => apps.push(app),\n    None => eprintln!(\"skipping malformed mas line: {line}\"),\n}","preventionTips":["Pin a known-good mas version in your environment","Run `mas list --json` once after mas upgrades to verify the schema","Keep mise updated so its mas parser tracks mas schema changes"],"tags":["macos","mas","json","package-manager"],"backgroundTag":"unexpected-response-shape","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}