withastro / astro · Issue No. 17595
Astro v7.1.6
Vite v8.1.5
Node v24.15.0
System macOS (arm64)
Package Manager npm
Output static
Adapter none
Integrations @astrojs/mdx (v7.0.5)
@astrojs/sitemap (v3.7.3)
No response
From Claude (apologies if anything is overstated):
At a large enough number of unique content-collection image references, the build fails with:
[PARSE_ERROR] Identifier `__ASTRO_IMAGE_IMPORT_26gozP` has already been declared
╭─[ .astro/content-assets.mjs:16929:8 ]
│
16929 │ import __ASTRO_IMAGE_IMPORT_26gozP from "../../../assets/generated/post-2588-body-3.png?astroContentImageFlag=&importer=src%2Fcontent%2Fblog%2Fpost-2588%2Findex.ru.md";
The two import statements sharing this identifier reference completely unrelated images from unrelated content entries:
import __ASTRO_IMAGE_IMPORT_26gozP from "../../../assets/generated/post-2588-body-3.png?astroContentImageFlag=&importer=src%2Fcontent%2Fblog%2Fpost-2588%2Findex.ru.md";
import __ASTRO_IMAGE_IMPORT_26gozP from "../../../assets/generated/post-2777-hero.jpg?astroContentImageFlag=&importer=src%2Fcontent%2Fblog%2Fpost-2777%2Findex.fil.md";
This is a hash collision, not a duplicate declaration of the same import. importIdToSymbolName() in packages/astro/src/assets/utils/resolveImports.ts derives the generated identifier by running the full import specifier (image path + importer query param) through shorthash() (packages/astro/src/runtime/server/shorthash.ts):
const importIdToSymbolName = (importId) => `__ASTRO_IMAGE_IMPORT_${shorthash(importId)}`;
shorthash()'s internal bitwise() function is a 32-bit rolling hash (hash = (hash << 5) - hash + charCode, then hash & hash to pin it to a 32-bit signed integer) before being base-61 encoded. Regardless of input string length, the output space is capped at 2³² (~4.29 billion) possible values.
Since content-collection images get one generated import per (image path, importing file) pair, a project with a large number of content entries referencing images (directly, or the same images repeated across many entries — e.g. translated content that duplicates hero/body images across locales) can easily generate hundreds of thousands of these import identifiers. At that volume, the birthday paradox makes collisions in a 32-bit space a near-certainty rather than a rare fluke.
The build should not fail due to two unrelated images being assigned the same generated import identifier.
https://github.com/AlanBreck/astro-image-import-collision-repro
Relay reads this issue against the repository's contribution signals: the files it is likely to touch, how the maintainers triage work this size, and what the first contribution would exercise.
The full analysis for this issue is still being assembled. Until then, the description above and the thread on GitHub are the most reliable context.