airbnb/epoxy · error · IllegalStateException

Failed to create regex for resource reference…

Error message

Failed to create regex for resource reference '$annotationReferencePrefix'

What it means

This IllegalStateException is thrown when the Epoxy annotation processor fails to compile a regex used to match import statements containing an R/R2 class reference (e.g. 'com.airbnb.paris.test.R2 as typeAliasedR'). The regex embeds the annotation reference prefix directly into the pattern, so a prefix containing regex metacharacters or malformed escape sequences causes PatternSyntaxException, which is rewrapped with the offending prefix to aid debugging of airbnb/epoxy#1265.

Solutions

  1. Inspect the reported '$annotationReferencePrefix' value in the message and find which character makes it an invalid regex; rename/fix the resource prefix or package fragment that produced it
  2. Update Epoxy to the latest processor version, where regex metacharacters in the prefix may be escaped or the underlying #1265 bug is fixed
  3. As a workaround, avoid type-aliased R imports ('import com.foo.R as R') in classes annotated with Epoxy model annotations, or import the R class directly
  4. File/check the epoxy issue tracker (#1265) if the prefix looks valid — the scanner may be passing the wrong string

Example fix

// before (in a build.gradle.kts with a resource prefix that leaks into the reference)
androidResources { prefix = "my-app_" }
// after
androidResources { prefix = "my_app_" }
// or in model code, avoid: import com.airbnb.epoxy.R as EpoxyR
Defensive patterns

Strategy: validation

Validate before calling

// before running the processor, sanity-check your resource prefix / R imports
val risky = Regex.containingMetaChars // conceptually:
fun prefixIsRegexSafe(prefix: String) =
    prefix.none { it in "\\()[]{}*+?|^$." }
if (!prefixIsRegexSafe(myResourcePrefix)) {
    throw IllegalArgumentException("Resource prefix '$myResourcePrefix' contains regex metacharacters")
}

Type guard

fun isRegexSafe(s: String): Boolean =
    runCatching { Regex("(.*)\\s+as\\s+" + Regex.escape(s) + "$") }.isSuccess

Prevention

When it happens

Trigger: findMatchingImportPackage builds Regex("(.*)\\s+as\\s+$annotationReferencePrefix$") and the annotationReferencePrefix value produces an invalid regex — e.g. it contains characters like '(', '[', '*' or a bad escape sequence. Reached via findMatchingImportPackageJava or findMatchingImportPackageKt when scanning Java/Kotlin imports for resource references.

Common situations: Unusual R class naming or generated R/R2 package fragments containing characters that are regex metacharacters (dashes, dots-adjacent brackets in package fragments, custom resource name prefixes), typically after Gradle namespace or resource prefix configuration changes. Historically seen with Kotlin type-aliased imports (issue #1265).

Related errors


AI-assisted analysis of airbnb/epoxy@e45bd3a61f (2026-09-13). Data as JSON: /api/errors/240ed440bd892931. Report an issue: GitHub.

Appendix: source

Thrown at epoxy-processor/src/main/java/com/airbnb/epoxy/processor/resourcescanning/KspResourceScanner.kt:431

            expression.getReferencedNameAsName()
        } else {
            null
        }
    }

    companion object {
        internal fun findMatchingImportPackage(
            importedNames: List<String>,
            annotationReference: String,
            annotationReferencePrefix: String,
            packageName: String
        ): ImportMatch {
            // Match something like "com.airbnb.paris.test.R2 as typeAliasedR"
            val typeAliasRegex = try {
                Regex("(.*)\\s+as\\s+$annotationReferencePrefix\$")
            } catch (e: PatternSyntaxException) {
                // Provide more information in this case so we can better debug https://github.com/airbnb/epoxy/issues/1265
                throw IllegalStateException("Failed to create regex for resource reference '$annotationReferencePrefix'", e)
            }

            return importedNames.firstNotNullOfOrNull { importedName ->

                when {
                    importedName.endsWith(".$annotationReferencePrefix") -> {
                        // import com.example.R
                        // R.layout.my_layout -> R
                        Normal(
                            referenceImportPrefix = importedName.substringBeforeLast(".$annotationReferencePrefix"),
                            annotationReference = annotationReference
                        )
                    }
                    importedName.contains(typeAliasRegex) -> {
                        typeAliasRegex.find(importedName)?.groupValues?.getOrNull(1)
                            ?.let { import ->
                                TypeAlias(import, annotationReferencePrefix, annotationReference)
                            }

View on GitHub (pinned to e45bd3a61f)