jdx/mise · error
mas list --json returned an app object without an ID and ver
Error message
mas list --json returned an app object without an ID and version
What it means
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.
Source
Thrown at src/system/packages/mas.rs:115
}
if let Ok(Value::Array(values)) = serde_json::from_str::<Value>(output) {
let apps: Vec<_> = values.iter().filter_map(parse_mas_json_value).collect();
if apps.is_empty() && !values.is_empty() {
bail!("mas list --json returned no parseable app objects");
}
return Ok(apps);
}
let mut apps = vec![];
for line in output
.lines()
.map(str::trim)
.filter(|line| !line.is_empty())
{
let value = serde_json::from_str::<Value>(line)
.map_err(|err| eyre!("mas list --json returned invalid JSON: {err}"))?;
match parse_mas_json_value(&value) {
Some(app) => apps.push(app),
None => bail!("mas list --json returned an app object without an ID and version"),
}
}
Ok(apps)
}
fn parse_mas_text(output: &str) -> Vec<InstalledApp> {
output
.lines()
.filter_map(|line| {
let (adam_id, rest) = line.trim().split_once(char::is_whitespace)?;
if !adam_id.chars().all(|c| c.is_ascii_digit()) {
return None;
}
let version = rest
.rsplit_once('(')
.and_then(|(_, v)| v.strip_suffix(')'))
.unwrap_or("")
.trim();View on GitHub (pinned to afd2eddd3a)
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
Example fix
// before
None => bail!("mas list --json returned an app object without an ID and version")
// after: tolerate the line and log instead of failing the whole listing
match parse_mas_json_value(&value) {
Some(app) => apps.push(app),
None => {
debug!("skipping mas json line without id/version: {value}");
}
} Defensive patterns
Strategy: validation
Validate before calling
fn looks_like_mas_app(v: &serde_json::Value) -> bool {
v.get("id").map_or(false, |i| i.is_number() || i.is_string())
&& v.get("version").map_or(false, |x| x.is_string() || x.is_number())
} Type guard
fn is_app_with_id_and_version(v: &Value) -> Option<(&Value, &Value)> {
Some((v.get("id")?, v.get("version")?))
} Try / catch
match parse_mas_json_value(&value) {
Some(app) => apps.push(app),
None => eprintln!("skipping malformed mas line: {line}"),
} Prevention
- 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
When it happens
Trigger: `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.
Common situations: 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.
Related errors
- mas app IDs must be numeric ADAM IDs (e.g. "mas:497799835")
- mas list failed: {}
- mas install requires a numeric ADAM ID ('{p}'); use `mas sea
- mas install failed: {}
- mas upgrade requires a numeric ADAM ID ('{p}'); use `mas sea
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/0f9546df78ceff89.
Report an issue: GitHub.