airbnb/epoxy · error · IllegalArgumentException
0 is an invalid value for required strings.
Error message
0 is an invalid value for required strings.
What it means
StringAttributeData validates that string resources passed to an Epoxy model attribute are non-zero. `0` is the Android framework's sentinel for 'no resource' and `Resources.getString(0)` would fail; Epoxy rejects it eagerly with `IllegalArgumentException` instead of letting a confusing NotFound crash happen later. Required string attributes must always receive a valid, non-zero resource ID or a literal string.
Solutions
- Pass a real, non-zero `@StringRes` resource ID (e.g. `R.string.title`) to the attribute.
- If the value may be absent, make the attribute optional with `.title(null)` via a nullable/text setter instead of passing 0.
- Set a literal string with `.title("Some text")` when you don't have a resource.
- Check upstream defaults: initialize resource-ID fields to `R.string.empty` or `View.NO_ID` and guard before calling the setter.
- Verify the failing resource actually exists in the right module so it isn't resolving to 0.
Example fix
// before
int titleRes = 0; // never assigned
model.title(titleRes); // throws
// after
if (titleRes != 0) {
model.title(titleRes);
} else {
model.title(R.string.default_title);
} Defensive patterns
Strategy: validation
Validate before calling
// Guard before calling a required string attribute
if (titleResId != 0) {
model.title(titleResId);
} else {
model.title(R.string.default_title); // or model.title(null) if optional
} Prevention
- Never initialize @StringRes/@PluralsRes fields to 0; use a real default resource.
- Prefer optional/nullable attribute setters when the value can be absent.
- Check defaults read from bundles/intents — getInt returns 0 for missing keys.
- Consider storing `View.NO_ID` and branching explicitly instead of passing it through.
When it happens
Trigger: Calling `setValue(0)` on a required string attribute — e.g. `.title(0)` or `.text(someResId)` where `someResId` defaulted to 0. Also happens when a generated model setter receives an uninitialized `@StringRes` field, or when `defaultStringRes` was left at 0 and the fallback path runs `setValue(0)`.
Common situations: A developer stores a resource ID in a field initialized to 0 and forgets to assign it; a server response lacks a value and the code passes 0 as a placeholder; a configurable attr is read from a config/bundle where the key is missing so `getInt` returns 0.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- numItemsToPrefetch must be greater than 0
- Must have stable ids when saving view holder state
- State cannot be restored once views have been bound. It…
- Tried to restore instance state, but onSaveInstanceState…
- Unable to invoke
AI-assisted analysis of airbnb/epoxy@e45bd3a61f (2026-09-13).
Data as JSON: /api/errors/33fe475499aec97e.
Report an issue: GitHub.
Appendix: source
Thrown at epoxy-adapter/src/main/java/com/airbnb/epoxy/StringAttributeData.java:71
if (stringRes != 0) {
this.stringRes = stringRes;
this.formatArgs = formatArgs;
string = null;
pluralRes = 0;
} else {
handleInvalidStringRes();
}
}
private void handleInvalidStringRes() {
if (hasDefault) {
if (defaultStringRes != 0) {
setValue(defaultStringRes);
} else {
setValue(defaultString);
}
} else {
throw new IllegalArgumentException("0 is an invalid value for required strings.");
}
}
public void setValue(@PluralsRes int pluralRes, int quantity, @Nullable Object[] formatArgs) {
if (pluralRes != 0) {
this.pluralRes = pluralRes;
this.quantity = quantity;
this.formatArgs = formatArgs;
string = null;
stringRes = 0;
} else {
handleInvalidStringRes();
}
}
public CharSequence toString(Context context) {
if (pluralRes != 0) {
if (formatArgs != null) {View on GitHub (pinned to e45bd3a61f)