badges/shields · error · InvalidResponse
undecodable content
Error message
undecodable content
What it means
fetchRepoContent() decodes GitHub's base64-encoded file content to UTF-8 and wraps any decoding failure in InvalidResponse 'undecodable content'. It is thrown when Buffer.from(content, 'base64')/toString produces or receives data that cannot be handled, meaning the repository file content isn't valid base64 or the expected shape changed. Treat it as an upstream data problem, not a bug in your request parameters.
Source
Thrown at services/github/github-common-fetch.js:43
async function fetchRepoContent(
serviceInstance,
{ user, repo, branch = 'HEAD', filename },
) {
const httpErrors = httpErrorsFor(
`repo not found, branch not found, or ${filename} missing`,
)
if (serviceInstance.staticAuthConfigured) {
const { content } = await serviceInstance._requestJson({
schema: contentSchema,
url: `/repos/${user}/${repo}/contents/${filename}`,
options: { searchParams: { ref: branch } },
httpErrors,
})
try {
return Buffer.from(content, 'base64').toString('utf-8')
} catch (e) {
throw new InvalidResponse({ prettyMessage: 'undecodable content' })
}
} else {
const { buffer } = await serviceInstance._request({
url: `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${filename}`,
httpErrors,
})
return buffer
}
}
async function fetchJsonFromRepo(
serviceInstance,
{ schema, user, repo, branch = 'HEAD', filename },
) {
if (serviceInstance.staticAuthConfigured) {
const buffer = await fetchRepoContent(serviceInstance, {
user,
repo,View on GitHub (pinned to 766fd8bc89)
Solutions
- Confirm the target file is under 1MB, or use the raw.githubusercontent.com / Git blobs API for large files.
- Retry the request — transient API issues can return incomplete payloads.
- Check that the requested file exists and is a regular text file, not a submodule, symlink, or directory listing.
Example fix
// before: fetching a 2MB config through the contents API /service/github/user/repo/config/large-config.json // after: keep tracked config files under 1MB or use raw content
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check file size via the contents API metadata
const meta = await fetch('https://api.github.com/repos/OWNER/REPO/contents/' + path).then(r => r.json());
if (meta.size > 1000000) throw new Error('file too large for base64 contents API'); Type guard
function isDecodableContent(content) {
return typeof content === 'string' && content.length > 0 && /^[A-Za-z0-9+/=\s]+$/.test(content);
} Try / catch
try {
const text = await fetchRepoContent({ user, repo, filename, branch });
} catch (e) {
if (e.prettyMessage === 'undecodable content') {
// fall back to raw.githubusercontent.com or the git blobs API
} else throw e;
} Prevention
- Keep files fetched via the contents API under 1MB.
- Prefer the raw endpoint for large or binary files.
- Handle content: null in GitHub API responses before decoding.
When it happens
Trigger: Requesting a file's content through the GitHub contents API (GraphQL or REST path used by configContent/buffer/content) where the returned `content` field is not valid base64 — e.g. file larger than 1MB so GitHub returns content: null, an empty string, or a malformed payload.
Common situations: Pointing the service at a file >1MB (contents API truncates/omits base64 content); binary files fetched via a route expecting base64 JSON; GitHub API response shape changes; requesting a file that is actually a Git LFS pointer in an unexpected path.
Related errors
- invalid branch
- Go version missing in go.mod
- invalid response data from auth endpoint
- unparseable svg response
- unparseable toml response
AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30).
Data as JSON: /api/errors/7dd01d950471845e.
Report an issue: GitHub.