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
- Edit config.toml and change `marketplace.sources` to array-of-tables form: `[[marketplace.sources]]` blocks
- Or remove the `sources` key entirely and re-run the add command (it will recreate it correctly)
- 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
- Write sources as [[marketplace.sources]] table blocks, never `sources = []` or `sources = "..."`
- Validate config.toml with a TOML linter after manual edits
- Let grok create the sources key the first time rather than pre-creating it
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
- paths.{key} is not an array
- Failed to create agent config: {e}
- Failed to load config: {e}
- Failed to parse config.toml: {e}
- refusing to write import marker: existing config at {} is no
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/00ccdb4f287de6c6.
Report an issue: GitHub.