can1357/oh-my-pi · error · Error

flickr getSizes response did not include a direct image URL

Error message

flickr getSizes response did not include a direct image URL

What it means

largestFlickrSource() iterates the sizes array from largest to smallest looking for a 'source' URL string; if none of the entries contain a usable source URL it throws this. The upload cannot produce a direct image link without at least one size URL.

Source

Thrown at packages/coding-agent/src/blob-broker/uploaders-image-hosts.ts:259

	const status = /<rsp\b[^>]*\b(?:stat|status)=["']([^"']+)["']/i.exec(xml)?.[1];
	if (status && status !== "ok") throw new Error("flickr rejected the upload");
	const photoId = /<photoid\b[^>]*>([^<]+)<\/photoid>/i.exec(xml)?.[1]?.trim();
	if (!photoId) throw new Error("flickr response did not include a photo ID");
	return photoId;
}

function largestFlickrSource(payload: Record<string, unknown>): string {
	if (payload.stat !== "ok") throw new Error("flickr getSizes request failed");
	const sizes = nestedRecord(payload, "sizes", "flickr").size;
	if (!Array.isArray(sizes)) throw new Error("flickr getSizes response did not include sizes");
	for (let index = sizes.length - 1; index >= 0; index--) {
		const size = sizes[index];
		if (size && typeof size === "object" && !Array.isArray(size)) {
			const source = (size as Record<string, unknown>).source;
			if (typeof source === "string" && source) return directUrl(source, "flickr");
		}
	}
	throw new Error("flickr getSizes response did not include a direct image URL");
}

function createFlickrUploader(config: DestinationRuntimeConfig): BlobUploader {
	const credentials: FlickrOAuthCredentials = {
		consumerKey: requireCredential(config, "apiKey"),
		consumerSecret: requireCredential(config, "apiSecret"),
		token: requireCredential(config, "oauthToken"),
		tokenSecret: requireCredential(config, "oauthTokenSecret"),
	};
	const uploadFields = flickrUploadFields(config);

	return {
		destination: "flickr",
		async upload(request: BlobUploadRequest) {
			const uploadOAuth = await oauthParameters("POST", FLICKR_UPLOAD_URL, uploadFields, credentials);
			const uploadResponse = await fetchFor(config)(FLICKR_UPLOAD_URL, {
				method: "POST",
				body: multipartFile(request, "photo", { ...uploadFields, ...uploadOAuth }),

View on GitHub (pinned to 9690622007)

Solutions

  1. Retry after a short delay so Flickr finishes generating image renditions
  2. Inspect the getSizes payload to confirm the source field is present on size entries
  3. Check the Flickr account's privacy/restriction settings for the uploaded photo
  4. Verify the Flickr API response format has not changed (source URL field name)

Example fix

// before
for (let index = sizes.length - 1; index >= 0; index--) {
	const size = sizes[index];
	if (size && typeof size === "object" && !Array.isArray(size)) {
		const source = (size as Record<string, unknown>).source;
		if (typeof source === "string" && source) return directUrl(source, "flickr");
	}
}
// after — fall back to the page URL when no direct source exists
const fallback = nestedRecord(payload, "sizes", "flickr").url;
if (typeof fallback === "string" && fallback) return directUrl(fallback, "flickr");
throw new Error("flickr getSizes response did not include a direct image URL");
Defensive patterns

Strategy: fallback

Validate before calling

const sizes = payload?.sizes?.size ?? [];
const anySource = (Array.isArray(sizes) ? sizes : []).some((s) => typeof s?.source === "string" && s.source);
if (!anySource) console.warn("no flickr size has a source URL yet");

Type guard

function hasDirectSource(payload: Record<string, unknown>): boolean {
	const sizes = (payload.sizes as Record<string, unknown> | undefined)?.size;
	return Array.isArray(sizes) && sizes.some((s) => typeof (s as Record<string, unknown>)?.source === "string");
}

Try / catch

try {
	return largestFlickrSource(payload);
} catch (err) {
	if (err instanceof Error && err.message.includes("direct image URL")) {
		return photoPageUrl(photoId); // fallback to the Flickr page URL
	}
	throw err;
}

Prevention

When it happens

Trigger: Every entry in the getSizes size array lacks a non-empty string 'source' field — e.g. all sizes are pending generation, the photo is restricted/hidden, or the response schema renamed the field.

Common situations: Flickr account with restricted content settings, brand-new photo whose renditions are not ready yet, or Flickr changing the source field name in getSizes output.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/2bf1136368cc55e3. Report an issue: GitHub.