{"record":{"id":"89fc4153144e7478","repo":"vercel/next.js","slug":"id-property-is-required-for-every-item-returned-fr-89fc41","errorCode":null,"errorMessage":"id property is required for every item returned from generateImageMetadata","messagePattern":"id property is required for every item returned from generateImageMetadata","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/next-core/src/next_app/metadata/route.rs","lineNumber":448,"sourceCode":"            if (typeof handler !== 'function') {{\n                throw new Error('Default export is missing in {resource_path}')\n            }}\n\n            export async function GET(_, ctx) {{\n                const paramsPromise = ctx.params\n                const idPromise = paramsPromise.then(params => params?.__metadata_id__)\n                const restParamsPromise = paramsPromise.then(params => {{\n                    if (!params) return undefined\n                    const {{ __metadata_id__, ...rest }} = params\n                    return rest\n                }})\n\n                const restParams = await restParamsPromise\n                const __metadata_id__ = await idPromise\n                const imageMetadata = await generateImageMetadata({{ params: restParams }})\n                const id = imageMetadata.find((item) => {{\n                    if (item?.id == null) {{\n                        throw new Error('id property is required for every item returned from generateImageMetadata')\n                    }}\n\n                    return item.id.toString() === __metadata_id__\n                }})?.id\n\n                if (id == null) {{\n                    return new NextResponse('Not Found', {{\n                        status: 404,\n                    }})\n                }}\n\n                return handler({{ params: restParamsPromise, id: idPromise }})\n            }}\n\n            export * from {resource_path}\n\n            export async function generateStaticParams({{ params }}) {{\n                const imageMetadata = await generateImageMetadata({{ params }})","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/crates/next-core/src/next_app/metadata/route.rs#L430-L466","documentation":"Thrown at request time (inside the GET handler of the generated multi-variant image route entry) when `generateImageMetadata()` returns an array in which one or more items have no `id` property (or `id == null`). Each variant must be addressable by id so Turbopack can build the `/[__metadata_id__]` segment, so the wrapper runs `imageMetadata.find(item => { if (item?.id == null) throw ... })`. Every returned item needs a unique, stringifiable `id`.","triggerScenarios":"Writing `export async function generateImageMetadata() { return [{ alt: 'logo' }, { alt: 'logo2' }] }` — no `id` on either item — then requesting any /icon route. The find() loop hits the first item, sees `item.id == null`, and throws.","commonSituations":"Returning plain objects without ids; returning a promise of objects whose `id` is conditionally set; mixing variant configs where only some carry `id`; copying a generic metadata array into generateImageMetadata.","solutions":["Ensure every object returned by `generateImageMetadata` has a truthy `id` (string or number): `[{ id: 'light', ... }, { id: 'dark', ... }]`.","Check for conditional ids that can evaluate to undefined/null and provide a fallback id.","Filter out placeholder/empty entries before returning them.","After fixing, the dev server will regenerate static params and the GET handler will resolve the matching id."],"exampleFix":"// before\nexport async function generateImageMetadata() {\n  return [\n    { alt: 'Light' },\n    { alt: 'Dark', id: 'dark' },\n  ]\n}\n\n// after — every item needs an id\nexport async function generateImageMetadata() {\n  return [\n    { id: 'light', alt: 'Light' },\n    { id: 'dark', alt: 'Dark' },\n  ]\n}","handlingStrategy":"validation","validationCode":"// Validate the generateImageMetadata output shape before returning.\nfunction assertImageMetadata(items: unknown[]): Array<{ id: string | number }> {\n  for (const item of items) {\n    if (item == null || (item as any).id == null) {\n      throw new Error('generateImageMetadata: every item needs a non-null `id`')\n    }\n  }\n  return items as Array<{ id: string | number }>\n}\nexport async function generateImageMetadata() {\n  return assertImageMetadata([{ id: 'light' }, { id: 'dark' }])\n}","typeGuard":"function hasId(item: unknown): item is { id: string | number } {\n  return typeof item === 'object' && item !== null && ['string','number'].includes(typeof (item as any).id)\n}","tryCatchPattern":null,"preventionTips":["Type the return of generateImageMetadata as `Array<{ id: string; ... }>`.","Add a unit test that every variant object has an id.","Never return placeholder objects without ids, even in dev."],"tags":["app-router","metadata-routes","image-metadata","generateimagemetadata","validation"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}