Skip to content

Asset request for generic @2x/@3x path fails when package only has platform-specific assets (.ios.png / .android.png) #2770

Description

@cl3i550n

Summary

When a dependency (e.g. react-native-calendars) ships image assets only as platform-specific files (e.g. previous@2x.ios.png and previous@2x.android.png) and no generic file (e.g. previous@2x.png), the Metro dev server returns 404 and throws:

Error: 'node_modules/react-native-calendars/src/calendar/img/previous@2x.png' could not be found, because it is not within the projectRoot or watchFolders, or it is blocked via the resolver.blockList config at getAsset (/path/to/node_modules/metro/src/Assets.js:226:13) at Server._processSingleAssetRequest (/path/to/node_modules/metro/src/Server.js:443:47)

The same happens for next@2x.png. Production/release builds work; the failure is development only (asset served by Metro on demand).

Environment

  • React Native: 0.83.x
  • Metro: 0.83.5 (likely 0.83.4+)
  • Package: e.g. react-native-calendars@1.1314.0 (assets under node_modules/.../src/calendar/img/)

Current behavior

  1. The app uses require('../img/previous.png') from the dependency (or equivalent).
  2. At runtime in dev, the client requests the asset by a path like .../img/previous@2x.png (generic density name, no platform suffix).
  3. In getAsset(), Metro uses fileExistsInFileMap(absolutePath) for that exact path.
  4. On disk the package only has previous@2x.ios.png and previous@2x.android.png, so previous@2x.png is not in the file map.
  5. The check fails and Metro throws the error above instead of resolving to the platform-specific asset (e.g. via getAbsoluteAssetRecord() / platform resolution).

So the failure is due to validating the requested path (generic @2x.png) against the file map, instead of treating it as a base name and resolving to the platform-specific file that actually exists.

Expected behavior

When the requested path is a “logical” asset name (e.g. .../previous@2x.png) and the package only ships platform-specific files (previous@2x.ios.png, previous@2x.android.png), Metro should either:

  • Resolve the requested path to the correct platform-specific asset before the fileExistsInFileMap check, or
  • Allow the request when a corresponding platform-specific file exists for that base name,

so that dev server asset serving is consistent with how the bundler resolves platform-specific assets at build time.

Related

  • Same pattern reported for @react-navigation/elements and back-icon@3x.png: #1667.
  • Affected package (example): react-native-calendars – only has previous@2x.ios.png / previous@2x.android.png and next@2x.ios.png / next@2x.android.png, no generic previous@2x.png / next@2x.png.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions