xai-org/grok-build · error

marketplace.sources is not an array of tables

Error message

marketplace.sources is not an array of tables

What it means

After parsing config.toml, the code expects `marketplace.sources` to be an Array of Tables (i.e. `[[marketplace.sources]]` entries). If the key exists but has a different TOML type (a plain table, string, or inline array), `as_array_of_tables_mut()` returns None and this error is raised instead of the code silently replacing the user's data.

Source

Thrown at crates/codegen/xai-grok-pager/src/plugin_cmd.rs:928

    };
    let config_path = xai_grok_config::grok_home().join(xai_grok_config::USER_CONFIG_FILENAME);

    let content = std::fs::read_to_string(&config_path).unwrap_or_default();
    let mut doc: toml_edit::DocumentMut = content
        .parse()
        .map_err(|e| anyhow::anyhow!("Failed to parse config.toml: {e}"))?;

    if doc.get("marketplace").is_none() {
        doc["marketplace"] = toml_edit::Item::Table(toml_edit::Table::new());
    }
    if doc["marketplace"].get("sources").is_none() {
        doc["marketplace"]["sources"] =
            toml_edit::Item::ArrayOfTables(toml_edit::ArrayOfTables::new());
    }

    let sources = doc["marketplace"]["sources"]
        .as_array_of_tables_mut()
        .ok_or_else(|| anyhow::anyhow!("marketplace.sources is not an array of tables"))?;

    let mut entry = toml_edit::Table::new();
    entry["name"] = toml_edit::value(&name);
    match &input {
        MarketplaceAddInput::GitUrl(git_url) => {
            entry["git"] = toml_edit::value(git_url);
        }
        MarketplaceAddInput::LocalPath(path) => {
            entry["path"] = toml_edit::value(path.display().to_string());
        }
    }
    sources.push(entry);

    std::fs::write(&config_path, doc.to_string())?;

    println!("Added marketplace source: {name} ({identity})");
    Ok(())
}

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Edit config.toml and change `marketplace.sources` to array-of-tables form: `[[marketplace.sources]]` blocks
  2. Or remove the `sources` key entirely and re-run the add command (it will recreate it correctly)
  3. Back up config.toml before editing

Example fix

// before (config.toml)
[marketplace]
sources = []
// after
[marketplace]
[[marketplace.sources]]
name = "example"
git = "https://example.com/repo.git"
Defensive patterns

Strategy: type-guard

Validate before calling

let content = std::fs::read_to_string(&config_path)?;
let doc = content.parse::<toml_edit::DocumentMut>()?;
let is_aot = doc.get("marketplace")
    .and_then(|m| m.get("sources"))
    .map(|s| s.as_array_of_tables().is_some())
    .unwrap_or(true); // absent is fine
if !is_aot { eprintln!("marketplace.sources must be [[marketplace.sources]] blocks"); }

Type guard

fn sources_is_array_of_tables(doc: &toml_edit::DocumentMut) -> bool {
    doc.get("marketplace")
        .and_then(|m| m.get("sources"))
        .map(|s| s.as_array_of_tables().is_some())
        .unwrap_or(true)
}

Try / catch

match doc["marketplace"]["sources"].as_array_of_tables_mut() {
    Some(sources) => sources.push(entry),
    None => eprintln!("config.toml: marketplace.sources has wrong type; use [[marketplace.sources]]"),
}

Prevention

When it happens

Trigger: Running `grok plugin marketplace add` when config.toml contains `marketplace.sources` defined as something other than `[[...]]` array-of-tables — e.g. `sources = "x"`, `sources = { }`, or an inline array `sources = [...]`.

Common situations: User hand-wrote `sources = []` or a single `[marketplace.sources]` non-list form; a different tool migrated the config to a different shape; older config format from a previous version of grok.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/00ccdb4f287de6c6. Report an issue: GitHub.