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

  1. Check `mas version` and upgrade mas to a current release so `--json` output matches the expected schema
  2. Run `mas list --json` manually and inspect which line/object is missing the id or version field
  3. Update mise to a version whose parse_mas_json_value understands the mas JSON schema in use
  4. 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

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


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/0f9546df78ceff89. Report an issue: GitHub.