react-navigation/react-navigation · error
Could not resolve color
Error message
Could not resolve color
What it means
The MaterialSymbolModule native module resolves a color for the Material Symbols icon bitmap via ColorPropConverter.getColor(colorValue, context). When the converter returns null — the value isn't a parseable color (int/resource/known string format such as #RRGGBB or a named color) — the module throws IllegalArgumentException('Could not resolve color'). This happens on Android inside getImageSource before the icon bitmap is generated.
Source
Thrown at packages/native/android/src/main/java/org/reactnavigation/MaterialSymbolModule.kt:50
private val fontHash: String by lazy {
reactApplicationContext.assets.open("fonts/MaterialSymbols.hash").bufferedReader().readText()
.trim()
}
override fun getImageSource(
name: String, variant: String?, weight: Double?, size: Double, color: ReadableMap
): String {
val colorValue = color.getDynamic("value").let {
when (it.type) {
com.facebook.react.bridge.ReadableType.Number -> it.asDouble()
com.facebook.react.bridge.ReadableType.Map -> it.asMap()
else -> null
}
}
val resolvedColor = ColorPropConverter.getColor(
colorValue, currentActivity ?: reactApplicationContext
) ?: throw IllegalArgumentException("Could not resolve color")
val density = reactApplicationContext.resources.displayMetrics.density
val scaledSize = (size * density).roundToInt().coerceAtLeast(1)
val (resolvedTypeface, typefaceSuffix) = MaterialSymbolTypeface.get(
reactApplicationContext, variant, weight?.toInt()
)
val cacheDir = File(
reactApplicationContext.cacheDir,
"react_navigation/material_symbols/$typefaceSuffix/$fontHash"
)
val cacheFile = File(
cacheDir, "${Uri.encode(name)}_${scaledSize}_$resolvedColor.png"
)
val cacheUri = cacheFile.toUri().toString()View on GitHub (pinned to ab1319d6bb)
Solutions
- Pass the color as a plain hex string like '#FF0000' or '#80FF0000' (AARRGGBB) which the converter reliably parses.
- If the color comes from a theme object, resolve it to a concrete string before calling (e.g. theme.colors.primary is fine, a nested object is not).
- Check that any referenced Android color resource actually exists in res/values/colors.xml.
- Guard the call: default to a known hex color when the value is null/undefined or not a string.
- If using PlatformColor objects, convert to hex for this API since ColorPropConverter may not support them here.
Example fix
// before
const source = await MaterialSymbol.getImageSource('home', 24, color); // color = {Qualifiers: {...}} or undefined
// after
const source = await MaterialSymbol.getImageSource('home', 24, typeof color === 'string' ? color : '#000000'); Defensive patterns
Strategy: try-catch
Validate before calling
const HEX_RE = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
function isResolvableColor(c) {
return typeof c === 'string' && HEX_RE.test(c);
} Type guard
function isResolvableColor(c: unknown): c is string {
return typeof c === 'string' && /^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(c);
} Try / catch
try {
const source = await MaterialSymbol.getImageSource('home', 24, color);
} catch (e) {
if (e instanceof Error && e.message.includes('Could not resolve color')) {
// fall back to a safe default color
const source = await MaterialSymbol.getImageSource('home', 24, '#000000');
} else {
throw e;
}
} Prevention
- Always pass colors as '#RRGGBB' or '#AARRGGBB' hex strings to native icon APIs.
- Resolve theme/PlatformColor objects to concrete hex strings before crossing the bridge.
- Coalesce nullish color values to a default before calling getImageSource.
- Verify any Android color resource referenced actually exists in res/values/colors.xml.
When it happens
Trigger: Calling getImageSource (or an API that uses it, e.g. a badge/tab icon helper) with a color prop that is an unsupported value on Android: a non-hex string, an rgba()/css-style string the converter can't parse, a JS object color (platformColor object not supported here), or null/undefined reaching the converter.
Common situations: Passing a theme-derived color object instead of a string, using 'rgba(0,0,0,0.5)' or named colors that the Android ColorPropConverter doesn't resolve in that app's context, passing a color resource name that doesn't exist in res/values, or forgetting the color argument so undefined is forwarded.
Related errors
- ${errors.join("\n")} Available variants: ${validVariants.jo
- Invalid color value: ${String(color)}
- MaterialSymbol is only supported on Android.
- MaterialSymbol.getImageSource is only supported on Android.
- SFSymbol is only supported on iOS.
AI-assisted analysis of react-navigation/react-navigation@ab1319d6bb (2026-08-31).
Data as JSON: /api/errors/bc271a0788c8a189.
Report an issue: GitHub.