aaif-goose/goose · error

Failed to parse {}: {}

Error message

Failed to parse {}: {}

What it means

goose scans the declarative-providers directory for *.json files and deserializes each into DeclarativeProviderConfig (a strict serde schema: required name/engine/display_name/base_url, typed models array, unknown setup fields rejected). When one file fails deserialization, the error embeds the full file path and the underlying serde message so you know exactly which JSON is broken and why.

Source

Thrown at crates/goose-providers/src/declarative.rs:290

    let mut config = deserialize_provider_config(json)?;
    resolve_config(&mut config)?;
    Ok(config)
}

pub fn load_custom_providers(dir: &Path) -> Result<Vec<DeclarativeProviderConfig>> {
    if !dir.exists() {
        return Ok(Vec::new());
    }

    std::fs::read_dir(dir)?
        .filter_map(|entry| {
            let path = entry.ok()?.path();
            (path.extension()? == "json").then_some(path)
        })
        .map(|path| {
            let content = std::fs::read_to_string(&path)?;
            deserialize_provider_config(&content)
                .map_err(|e| anyhow::anyhow!("Failed to parse {}: {}", path.display(), e))
        })
        .collect()
}

pub fn from_json(
    json: &str,
    tls_config: Option<TlsConfig>,
    key_resolver: impl KeyResolver,
) -> Result<Box<dyn Provider>> {
    let config = config_from_json(json)?;

    match config.engine {
        ProviderEngine::OpenAI => openai::from_declarative_config(config, tls_config, key_resolver)
            .map(|provider| Box::new(provider.build()) as Box<dyn Provider>),
        ProviderEngine::Ollama => ollama::from_declarative_config(config, tls_config, key_resolver)
            .map(|provider| Box::new(provider.build()) as Box<dyn Provider>),
        ProviderEngine::Anthropic => {
            anthropic::from_declarative_config(config, tls_config, key_resolver)

View on GitHub (pinned to 3810898a74)

Solutions

  1. Read the message: it names the file and the serde error (e.g. 'missing field `engine` at line 3') — open that exact file and fix the cited field
  2. Validate the file against a known-good bundled provider JSON (same top-level keys: name, engine, display_name, base_url, models, env_vars...)
  3. Run it through a JSON linter (jq . file.json) to catch syntax errors first
  4. If the file isn't meant to be a provider, move it out of the scanned directory or rename the extension away from .json

Example fix

// before (broken file.json)
{ "name": "my-provider", "engine": "openai_compatible", "base_url": "https://api.x.com/v1" } // missing display_name

// after
{ "name": "my-provider", "engine": "openai_compatible", "display_name": "My Provider", "base_url": "https://api.x.com/v1", "models": [] }
Defensive patterns

Strategy: try-catch

Validate before calling

fn provider_json_valid(path: &std::path::Path) -> anyhow::Result<()> {
    let text = std::fs::read_to_string(path)?;
    serde_json::from_str::<serde_json::Value>(&text)?; // syntax
    deserialize_provider_config(&text)?;                // schema
    Ok(())
}

Try / catch

// Don't let one bad file kill the whole scan: collect per-file outcomes, skip
// invalid files with a warning, and report them together:
let mut ok = Vec::new();
for path in json_files {
    match try_load(&path) {
        Ok(cfg) => ok.push(cfg),
        Err(e) => eprintln!("warning: skipping {}: {e}", path.display()),
    }
}

Prevention

When it happens

Trigger: Any .json file in the scanned providers dir that: misses a required field ('engine', 'base_url', ...), has a wrong type ("context_limit": "4096" as string), an unknown field inside 'setup', invalid JSON syntax (trailing comma, unquoted key), or an engine value serde can't map.

Common situations: Hand-authored custom provider JSON with a typo'd or missing key; files edited with an editor that broke JSON syntax; copying a config snippet from docs for a different goose version whose schema changed; leaving a template/example file with placeholder values in the directory.

Understand the failure class

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/25b27e7adf57d23d. Report an issue: GitHub.