Skip to content

[pigeon] ProxyApi classes throws IllegalArgumentException on slow android phones #174125

@JavesonYehudi

Description

@JavesonYehudi

Steps to reproduce

We use a wrapper around the Auth0 library, leveraging Proxy to support our use case. Recently, we observed that some users on slower Android devices encounter a strange exception that shouldn’t happen.
The exception occurs even though the generated code correctly maps the model that triggers it.
Through testing, we discovered that introducing even a very small delay (e.g., 1 millisecond) in object creation can reproduce the issue. This suggests that on slower devices, building the Credentials object may take slightly longer, causing an Unsupported value exception.

Steps to reproduce:

  1. Create a new flutter plugin
  2. Add a pigeon configuration file with the following code:
import 'package:pigeon/pigeon.dart';

@ConfigurePigeon(
  PigeonOptions(
    dartOut: 'lib/src/pigeon_generated/credentials.pigeon.dart',
    kotlinOut:
        'android/src/main/kotlin/com/example/proxy_bug_report/generated/CredentialsApi.g.kt',
    dartPackageName: 'com.example.proxy_bug_report',
  ),
)
@ProxyApi(
  kotlinOptions: KotlinProxyApiOptions(
    fullClassName: 'com.example.proxy_bug_report.Auth',
  ),
)
abstract class Auth {
  Auth();

  @async
  Credentials login();
}

@ProxyApi(
  kotlinOptions: KotlinProxyApiOptions(
    fullClassName: 'com.example.proxy_bug_report.Credentials',
  ),
)
abstract class Credentials {
  late final String accessToken;
}
  1. Generate the pigeon classes
  2. In the generated PigeonProxyApiBaseCodec Kotlin class, update writeValue by adding a small delay when creating Credentials:
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
    if (value is Boolean || value is ByteArray || value is Double || value is DoubleArray || value is FloatArray || value is Int || value is IntArray || value is List<*> || value is Long || value is LongArray || value is Map<*, *> || value is String || value == null) {
      super.writeValue(stream, value)
      return
    }

    if (value is com.example.proxy_bug_report.Auth) {
      registrar.getPigeonApiAuth().pigeon_newInstance(value) { }
    } else if (value is com.example.proxy_bug_report.Credentials) {
      android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
        registrar.getPigeonApiCredentials().pigeon_newInstance(value) { }
      }, 1)
    }

    when {
      registrar.instanceManager.containsInstance(value) -> {
        stream.write(128)
        writeValue(stream, registrar.instanceManager.getIdentifierForStrongReference(value))
      }

      else -> throw IllegalArgumentException("Unsupported value: '$value' of type '${value.javaClass.name}'")
    }
  }
  1. Try to call the login method

Expected results

The Credentials object with the access token

Actual results

Unsupported value: 'Credentials(accessToken=access_token)' of type 'com.example.proxy_bug_report.Credentials'

Code sample

code sample here

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.29.3, on macOS 15.6 24G84 darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.1)
[✓] Xcode - develop for iOS and macOS (Xcode 16.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2025.1)
[✓] IntelliJ IDEA Ultimate Edition (version 2024.3.3)
[✓] IntelliJ IDEA Ultimate Edition (version 2025.2)
[✓] VS Code (version 1.102.3)
[✓] VS Code (version 1.99.3)
[✓] Connected device (5 available)
[✓] Network resources

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    r: invalidIssue is closed as not valid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions