aaif-goose/goose · error

Failed to convert content to string: {}

Error message

Failed to convert content to string: {}

What it means

The base64 decode succeeded but String::from_utf8 rejected the decoded bytes — the recipe file on GitHub contains byte sequences that are not valid UTF-8. Goose requires recipe files to be UTF-8 text; the decoded payload is likely Latin-1/Windows-1252 text or binary data committed by mistake.

Source

Thrown at crates/goose-cli/src/recipes/github_recipe.rs:362

        return Err(anyhow!(
            "Failed to access recipe file: {}/{}",
            dir_name,
            recipe_filename
        ));
    }

    let file_info: Value = serde_json::from_slice(&output.stdout)
        .map_err(|e| anyhow!("Failed to parse file info: {}", e))?;

    if let Some(content_b64) = file_info.get("content").and_then(|c| c.as_str()) {
        // Decode base64 content
        use base64::{engine::general_purpose, Engine as _};
        let content_bytes = general_purpose::STANDARD
            .decode(content_b64.replace('\n', ""))
            .map_err(|e| anyhow!("Failed to decode base64 content: {}", e))?;

        let content = String::from_utf8(content_bytes)
            .map_err(|e| anyhow!("Failed to convert content to string: {}", e))?;

        // Parse the recipe content
        let (recipe, _) = parse_recipe_content(&content, Some(format!("{}/{}", repo, dir_name)))?;

        return Ok(RecipeInfo {
            name: dir_name.to_string(),
            source: RecipeSource::GitHub,
            path: format!("{}/{}", repo, dir_name),
            title: Some(recipe.title),
            description: Some(recipe.description),
        });
    }

    Err(anyhow!("Failed to get recipe content from GitHub"))
}

#[cfg(test)]
mod tests {

View on GitHub (pinned to 3810898a74)

Solutions

  1. Identify the encoding: `gh api repos/{repo}/contents/{dir}/recipe.yaml -q .download_url` then `curl -sL <url> | file -`.
  2. Re-encode the file as UTF-8 in the upstream repo (iconv -f WINDOWS-1252 -t UTF-8) and fix or delete binary junk.
  3. Re-run goose recipe loading after the fix is pushed.

Example fix

# before: file saved as Windows-1252
$ curl -sL <download_url> | file -
recipe.yaml: ISO-8859 text

# after
$ iconv -f WINDOWS-1252 -t UTF-8 recipe.yaml > recipe.utf8.yaml && mv recipe.utf8.yaml recipe.yaml
git commit -am "convert recipe to UTF-8" && git push
Defensive patterns

Strategy: validation

Validate before calling

# verify the file decodes as UTF-8 before goose loads it
curl -sL "$(gh api repos/${REPO}/contents/${DIR}/recipe.yaml --jq .download_url)" \
  | iconv -f UTF-8 -t UTF-8 >/dev/null && echo utf8-ok || echo "not UTF-8"

Try / catch

match to_string(bytes) {
    Err(e) if e.to_string().contains("convert content to string") => {
        eprintln!("recipe file is not UTF-8 — re-encode upstream");
    }
    r => r,
}

Prevention

When it happens

Trigger: A recipe.yaml saved on Windows in ANSI/Latin-1 encoding with smart quotes or accented characters; a binary or UTF-16 file committed as recipe.yaml.

Common situations: Editors saving YAML with a BOM-less legacy codepage; UTF-16 exports; accidentally committed .swp/.zip renamed to recipe.yaml.

Related errors


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