paperclipai/paperclip · warning · GitHubAttachmentUnavailableError
github_attachment_canonical_file_unsupported
github_attachment_canonical_file_unsupported
Error message
github_attachment_canonical_file_unsupported
What it means
GitHubAttachmentUnavailableError with code github_attachment_canonical_file_unsupported is thrown when the attachment locator URL does not end in /assets/<uuid>, i.e. it is not a GitHub user-upload image asset. Only image assets on GitHub's asset hosts have a documented signed-download representation; generic private files (e.g. repository files or other upload kinds) deliberately cannot be canonicalized to a signed URL.
Source
Thrown at server/src/services/chat-github-attachments.ts:594
if (
row.pull_request_url !==
`https://api.github.com/repos/${thread[1]}/pulls/${thread[3]}` ||
String(row.in_reply_to_id ?? row.id) !== thread[4]
)
throw new GitHubAttachmentUnavailableError(
"github_attachment_canonical_source_mismatch",
);
} else if (
row.issue_url !==
`https://api.github.com/repos/${thread[1]}/issues/${thread[3]}`
)
throw new GitHubAttachmentUnavailableError(
"github_attachment_canonical_source_mismatch",
);
const assetId = /\/assets\/([a-f0-9-]+)$/i.exec(locator.url)?.[1];
// Generic private files have no documented signed-download representation.
if (!assetId)
throw new GitHubAttachmentUnavailableError(
"github_attachment_canonical_file_unsupported",
);
const sourceBody = row.body;
const imagePath = new RegExp(
`^/[1-9][0-9]*/[1-9][0-9]*-${assetId}\\.(?:png|jpe?g|gif|webp)$`,
"i",
);
const sameAssetImage = (src: string): URL | null => {
const target = allowedRedirect(src, locator.url);
return target?.hostname === "private-user-images.githubusercontent.com" &&
imagePath.test(target.pathname)
? target
: null;
};
const signedImage = (src: string): URL | null => {
const target = sameAssetImage(src);
return target &&
[...target.searchParams.keys()].join(",") === "jwt" &&View on GitHub (pinned to 01ad858492)
Solutions
- Only run canonical resolution for image attachments whose URL ends in /assets/<uuid> (png/jpg/gif/webp).
- For non-image or generic files, serve them through the direct download path instead of signed-URL canonicalization.
- Check how the attachment handle was created; fix upstream URL extraction to preserve the /assets/<uuid> form.
Example fix
// before resolveGitHubCommentAttachmentTarget(fileAttachment, row); // after if (/\/assets\/[a-f0-9-]+$/i.test(attachment.url)) resolveGitHubCommentAttachmentTarget(attachment, row);
Defensive patterns
Strategy: type-guard
Validate before calling
const isImageAsset = (url: string) => /\/assets\/[a-f0-9-]+\.(png|jpe?g|gif|webp)?/i.test(url) || /\/assets\/[a-f0-9-]+$/i.test(url); if (!isImageAsset(attachment.url)) useDirectDownloadPath(attachment);
Type guard
const isCanonicalizable = (a: Attachment): boolean => /\/assets\/[a-f0-9-]+$/i.test(a.url);
Try / catch
try {
return await prepareGitHubPublicAttachment(attachment);
} catch (e) {
if (e instanceof GitHubAttachmentUnavailableError && e.code === 'github_attachment_canonical_file_unsupported')
return directDownload(attachment);
throw e;
} Prevention
- Classify attachments as image-asset vs generic file at ingestion time.
- Route only /assets/<uuid> URLs through canonical resolution.
- Keep the original user-attachments/assets URL form intact during extraction.
- Document that generic private files are unsupported for signed canonicalization.
When it happens
Trigger: Calling resolveGitHubCommentAttachmentTarget for an attachment whose locator.url lacks a trailing /assets/<hex-uuid> segment — e.g. github user-attachments URLs of a non-asset form, or arbitrary file links pasted in a comment.
Common situations: Attachments created from generic file URLs (PDFs, zips, non-image user-attachments); URLs copied from rendered markdown where GitHub rewrites asset links; attempting canonical resolution for attachment kinds the feature never supported.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- github_attachment_canonical_image_count_invalid
- github_attachment_canonical_mapping_ambiguous
- github_attachment_canonical_html_unavailable
- github_attachment_canonical_target_denied
- github_attachment_canonical_image_without_source_anchor
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/12b6fab7e7939aeb.
Report an issue: GitHub.