{"record":{"id":"7e655f478afea8a8","repo":"DIYgod/RSSHub","slug":"no-thumbnails-available","errorCode":null,"errorMessage":"no thumbnails available","messagePattern":"no thumbnails available","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"warning","filePath":"lib/routes/telegram/channel-media.ts","lineNumber":83,"sourceCode":"    return 0;\n}\n\nfunction chooseLargestThumb(thumbs: Api.TypePhotoSize[]) {\n    thumbs = [...thumbs].toSorted((a, b) => sortThumb(a) - sortThumb(b));\n    return thumbs.pop();\n}\n\nexport async function* streamThumbnail(client: TelegramClient, doc: Api.Document) {\n    if ((doc.thumbs?.length ?? 0) > 0) {\n        const size = chooseLargestThumb(doc.thumbs!);\n        if (size instanceof Api.PhotoCachedSize || size instanceof Api.PhotoStrippedSize) {\n            yield ExpandInlineBytes(size.bytes);\n        } else {\n            yield* streamDocument(client, doc, size && 'type' in size ? size.type : '');\n        }\n        return;\n    }\n    throw new Error('no thumbnails available');\n}\n\nexport async function* streamDocument(client: TelegramClient, obj: Api.Document, thumbSize = '', offset?: bigInt.BigInteger, limit?: bigInt.BigInteger) {\n    const requestSize = 512 * 1024; // MAX_CHUNK_SIZE\n    let skip = offset ? offset.mod(requestSize).toJSNumber() : 0;\n    const alignedOffset = offset?.subtract(skip);\n    // console.log('starting iterDownload');\n    const chunks = client.iterDownload(\n        new Api.InputDocumentFileLocation({\n            id: obj.id,\n            accessHash: obj.accessHash,\n            fileReference: obj.fileReference,\n            thumbSize,\n        }),\n        {\n            requestSize,\n            dcId: obj.dcId,\n            offset: alignedOffset,","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/telegram/channel-media.ts#L65-L101","documentation":"streamThumbnail throws when a Telegram Api.Document has no thumbnails (doc.thumbs is undefined or an empty array). With no thumb to select, there is nothing to stream as a preview image for that document.","triggerScenarios":"A media request resolves to a document that legitimately carries no thumbnail (e.g. an audio file, a document without a preview, or a file whose thumbs were stripped). chooseLargestThumb is never reached because the length check short-circuits.","commonSituations":"Channel post points at an audio/sticker/file document without a thumbnail; the requested media type was a video whose thumbnail failed to populate; calling streamThumbnail instead of streamDocument for a non-image media.","solutions":["Fall back to streamDocument(client, doc) for the full media when there is no thumbnail, instead of throwing.","At the call site, check doc.thumbs?.length before choosing streamThumbnail vs streamDocument so non-previewable media is handled gracefully.","Return a 404/empty-thumbnail response to the client rather than crashing the route handler."],"exampleFix":"// before\nif ((doc.thumbs?.length ?? 0) > 0) {\n    ... return;\n}\nthrow new Error('no thumbnails available');\n\n// after: fall back to the full document stream\nif ((doc.thumbs?.length ?? 0) > 0) {\n    ...\n    return;\n}\n// no thumbnail; serve the original file instead of erroring\nyield* streamDocument(client, doc);","handlingStrategy":"validation","validationCode":"function hasThumbnail(doc: Api.Document): boolean {\n    return Array.isArray(doc.thumbs) && doc.thumbs.length > 0;\n}\n// if (!hasThumbnail(doc)) { serve the full document instead of a thumbnail }","typeGuard":"function docHasThumbs(doc: Api.Document): doc is Api.Document & { thumbs: Api.TypePhotoSize[] } {\n    return Array.isArray(doc.thumbs) && doc.thumbs.length > 0;\n}","tryCatchPattern":"try {\n    yield* streamThumbnail(client, doc);\n} catch (e) {\n    if (e instanceof Error && /no thumbnails available/.test(e.message)) {\n        yield* streamDocument(client, doc); // full media fallback\n        return;\n    }\n    throw e;\n}","preventionTips":["Check doc.thumbs?.length at the call site before choosing streamThumbnail.","Default to streamDocument for media types that commonly lack previews (audio, files).","Treat a missing thumbnail as a soft condition, not an error, for media-serving routes."],"tags":["media","telegram","validation"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}