{"record":{"id":"e4cde7e8c06cebf1","repo":"can1357/oh-my-pi","slug":"flickr-response-did-not-include-a-photo-id","errorCode":null,"errorMessage":"flickr response did not include a photo ID","messagePattern":"flickr response did not include a photo ID","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/uploaders-image-hosts.ts","lineNumber":244,"sourceCode":"\t\t[\"isPublic\", \"is_public\"],\n\t\t[\"isFriend\", \"is_friend\"],\n\t\t[\"isFamily\", \"is_family\"],\n\t\t[\"safetyLevel\", \"safety_level\"],\n\t\t[\"contentType\", \"content_type\"],\n\t\t[\"hidden\", \"hidden\"],\n\t] as const;\n\tfor (const [option, parameter] of mappings) {\n\t\tconst value = optionString(config, option);\n\t\tif (value) fields[parameter] = value;\n\t}\n\treturn fields;\n}\n\nfunction flickrPhotoId(xml: string): string {\n\tconst status = /<rsp\\b[^>]*\\b(?:stat|status)=[\"']([^\"']+)[\"']/i.exec(xml)?.[1];\n\tif (status && status !== \"ok\") throw new Error(\"flickr rejected the upload\");\n\tconst photoId = /<photoid\\b[^>]*>([^<]+)<\\/photoid>/i.exec(xml)?.[1]?.trim();\n\tif (!photoId) throw new Error(\"flickr response did not include a photo ID\");\n\treturn photoId;\n}\n\nfunction largestFlickrSource(payload: Record<string, unknown>): string {\n\tif (payload.stat !== \"ok\") throw new Error(\"flickr getSizes request failed\");\n\tconst sizes = nestedRecord(payload, \"sizes\", \"flickr\").size;\n\tif (!Array.isArray(sizes)) throw new Error(\"flickr getSizes response did not include sizes\");\n\tfor (let index = sizes.length - 1; index >= 0; index--) {\n\t\tconst size = sizes[index];\n\t\tif (size && typeof size === \"object\" && !Array.isArray(size)) {\n\t\t\tconst source = (size as Record<string, unknown>).source;\n\t\t\tif (typeof source === \"string\" && source) return directUrl(source, \"flickr\");\n\t\t}\n\t}\n\tthrow new Error(\"flickr getSizes response did not include a direct image URL\");\n}\n\nfunction createFlickrUploader(config: DestinationRuntimeConfig): BlobUploader {","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/uploaders-image-hosts.ts#L226-L262","documentation":"This error is thrown by flickrPhotoId() when parsing the XML response from Flickr's upload API: the response either had no <photoid> element or it was empty. Flickr only returns a photo ID after a successful upload, so a missing ID means the upload result cannot be turned into a public URL.","triggerScenarios":"The Flickr upload endpoint returned HTTP 200 but the XML body lacked a <photoid>...</photoid> element — e.g. an unexpected response envelope, a proxy/error page returned with status ok absent, or the regex stat attribute parsed as 'ok' while the body was truncated or HTML.","commonSituations":"Flickr API changes or deprecation, an API key without upload permission returning an unusual response, a corporate proxy or captive portal injecting HTML, or network gear truncating the response body.","solutions":["Verify the Flickr API key/secret credentials in the destination config are valid and have upload scope","Log the raw XML response from the upload call to see what Flickr actually returned","Check whether the response is HTML (proxy/portal interception) and whitelist the api.flickr.com endpoint","Retry the upload; if it persists, confirm the Flickr upload API contract is unchanged"],"exampleFix":"// before\nconst photoId = /<photoid\\b[^>]*>([^<]+)<\\/photoid>/i.exec(xml)?.[1]?.trim();\n// after — log the payload to diagnose\nconst photoId = /<photoid\\b[^>]*>([^<]+)<\\/photoid>/i.exec(xml)?.[1]?.trim();\nif (!photoId) throw new Error(`flickr response did not include a photo ID: ${xml.slice(0, 500)}`);","handlingStrategy":"try-catch","validationCode":"const looksLikeFlickrRsp = (xml: string) => /<rsp\\b[^>]*stat=[\"']ok[\"']/i.test(xml) && /<photoid\\b[^>]*>[^<]+<\\/photoid>/i.test(xml);\nif (!looksLikeFlickrRsp(rawXml)) console.warn(\"flickr upload response lacks photoid; aborting URL resolution\");","typeGuard":"function hasPhotoId(xml: string): boolean {\n\treturn /<photoid\\b[^>]*>([^<]+)<\\/photoid>/i.test(xml);\n}","tryCatchPattern":"try {\n\tconst id = flickrPhotoId(xml);\n} catch (err) {\n\tif (err instanceof Error && err.message.includes(\"photo ID\")) {\n\t\t// log raw xml, fall back to re-upload or alternate host\n\t}\n\tthrow err;\n}","preventionTips":["Log the raw Flickr XML on every upload for diagnosability","Validate credentials have upload scope before deploying","Detect HTML/proxy interception by checking the response starts with '<?xml'","Keep the Flickr API integration current with upstream changes"],"tags":["flickr","upload","response-parsing","xml"],"backgroundTag":"upload-response-missing-field","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}