{"record":{"id":"baf6d4c5252cb424","repo":"aaif-goose/goose","slug":"failed-to-convert-content-to-string","errorCode":null,"errorMessage":"Failed to convert content to string: {}","messagePattern":"Failed to convert content to string: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-cli/src/recipes/github_recipe.rs","lineNumber":362,"sourceCode":"        return Err(anyhow!(\n            \"Failed to access recipe file: {}/{}\",\n            dir_name,\n            recipe_filename\n        ));\n    }\n\n    let file_info: Value = serde_json::from_slice(&output.stdout)\n        .map_err(|e| anyhow!(\"Failed to parse file info: {}\", e))?;\n\n    if let Some(content_b64) = file_info.get(\"content\").and_then(|c| c.as_str()) {\n        // Decode base64 content\n        use base64::{engine::general_purpose, Engine as _};\n        let content_bytes = general_purpose::STANDARD\n            .decode(content_b64.replace('\\n', \"\"))\n            .map_err(|e| anyhow!(\"Failed to decode base64 content: {}\", e))?;\n\n        let content = String::from_utf8(content_bytes)\n            .map_err(|e| anyhow!(\"Failed to convert content to string: {}\", e))?;\n\n        // Parse the recipe content\n        let (recipe, _) = parse_recipe_content(&content, Some(format!(\"{}/{}\", repo, dir_name)))?;\n\n        return Ok(RecipeInfo {\n            name: dir_name.to_string(),\n            source: RecipeSource::GitHub,\n            path: format!(\"{}/{}\", repo, dir_name),\n            title: Some(recipe.title),\n            description: Some(recipe.description),\n        });\n    }\n\n    Err(anyhow!(\"Failed to get recipe content from GitHub\"))\n}\n\n#[cfg(test)]\nmod tests {","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/recipes/github_recipe.rs#L344-L380","documentation":"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.","triggerScenarios":"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.","commonSituations":"Editors saving YAML with a BOM-less legacy codepage; UTF-16 exports; accidentally committed .swp/.zip renamed to recipe.yaml.","solutions":["Identify the encoding: `gh api repos/{repo}/contents/{dir}/recipe.yaml -q .download_url` then `curl -sL <url> | file -`.","Re-encode the file as UTF-8 in the upstream repo (iconv -f WINDOWS-1252 -t UTF-8) and fix or delete binary junk.","Re-run goose recipe loading after the fix is pushed."],"exampleFix":"# before: file saved as Windows-1252\n$ curl -sL <download_url> | file -\nrecipe.yaml: ISO-8859 text\n\n# after\n$ iconv -f WINDOWS-1252 -t UTF-8 recipe.yaml > recipe.utf8.yaml && mv recipe.utf8.yaml recipe.yaml\ngit commit -am \"convert recipe to UTF-8\" && git push","handlingStrategy":"validation","validationCode":"# verify the file decodes as UTF-8 before goose loads it\ncurl -sL \"$(gh api repos/${REPO}/contents/${DIR}/recipe.yaml --jq .download_url)\" \\\n  | iconv -f UTF-8 -t UTF-8 >/dev/null && echo utf8-ok || echo \"not UTF-8\"","typeGuard":null,"tryCatchPattern":"match to_string(bytes) {\n    Err(e) if e.to_string().contains(\"convert content to string\") => {\n        eprintln!(\"recipe file is not UTF-8 — re-encode upstream\");\n    }\n    r => r,\n}","preventionTips":["Configure editors to save YAML as UTF-8 without legacy codepages.","Add a repo lint (CI) that rejects non-UTF-8 recipe files."],"tags":["utf-8","encoding","github","recipes"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}