new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Expo · Router · all subjects

file-based-routes & api routes

21 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Integer overflow: file and media sizes must use Long not Int

File, media, and buffer sizes must always use Long, never Int. Android's own APIs return Long for these, and a narrowing conversion to Int silently wraps past 2 GB. Check every .toInt(), Int parameter, and arithmetic that multiplies dimensions. Example defect: createAssetAsync failing for files larger than ~2 GB.

SDK level gating requirements for minSdk 24 to targetSdk 36

minSdk is 24 and targetSdk is 36. Platform APIs, constants, or flags must be guarded with Build.VERSION.SDK_INT at the correct level matching the API's @RequiresApi annotation. Also guard behavior changes (APIs that exist at minSdk but do something different on later levels), capability checks that gate usage not just capability detection, and new targetSdk-triggered behaviors like background restrictions, exact alarms, foreground service types, predictive back, and PendingIntent mutability.

R8 minification requires keep rules for reflection, JNI, and name lookups

Release builds run R8. Classes, fields, or methods reached by reflection, JNI, or name lookup require matching keep rules in the package's proguard-rules.pro or consumer-rules.pro. This includes Record subclasses, enum valueOf, Gson/Moshi models, and anything named from C++. Any Class.forName, getDeclaredMethod, or annotation scan introduced needs a keep rule in the same diff.

Blocking I/O must not occur in synchronous Function bodies

Blocking work like file or network I/O, ContentResolver queries, Thread.sleep, runBlocking, CountDownLatch.await, bitmap decode, and database access must not be inside a synchronous Function(...) body. Move it to AsyncFunction or AsyncFunction … Coroutine.

Long-running blocking work in AsyncFunction requires context switching

Long-running blocking work in an AsyncFunction must not stay on the default queue. Hop off with withContext(Dispatchers.IO) in a Coroutine body, or .runOnQueue(appContext.backgroundCoroutineScope). Inside a View { … } block always hop off because view async functions cannot use the coroutine form. Cleanup operations like response.close() or stream close after a withContext block runs back on the shared serial queue, so they must also be moved off.

JSI objects must be accessed from correct context via runtime.schedule

JSI wrappers (JavaScriptObject, JavaScriptValue, JavaScriptFunction, JavaScriptWeakObject, or ArrayBuffer unscoped accessors) touched from a background context must route through runtime.schedule { }.

ContentResolver queries must use selectionArgs, not string concatenation

ContentResolver selection strings must be built using selectionArgs, never by string concatenation. Identifier lists must be escaped. Example defect: missing escaping for calendarIds.

Bitmap decode must downsample to target bounds

Full-resolution decode without downsample against target bounds wastes memory. A 12 MP JPEG becomes a ~48 MB ARGB_8888 bitmap regardless of requested display size. Use BitmapFactory.Options.inSampleSize or hand decoding to Coil/Glide.

sendEvent names must match Events(...) declaration

A sendEvent("name", …) call requires that "name" is present in that module's Events(…) declaration. Also flag removing a name from Events(...) while sendEvent calls remain.

Kotlin Record properties require @Field annotation with correct key

A new or renamed property on a Kotlin Record must have a @Field annotation. The @Field(key = …) must match the key the TypeScript side sends.

Kotlin Record constructor parameters must have defaults

Every primary-constructor parameter added to a Kotlin Record or ComposeProps must keep a default value.

Use CodedException subclasses instead of raw exceptions for JS branching

Where JavaScript branches on failure, throw a CodedException subclass instead of raw IllegalArgumentException, IllegalStateException, or bare Exception. The core library wraps those as ERR_UNEXPECTED.

Error messages must explain what, why, and how

Error messages must state what failed, why it failed, and how to fix it. A message stating only what failed is incomplete.

Listener registration must have matching removal in same diff

Long-lived or process-global listeners registered from a module (registerContentObserver, registerReceiver, sensor or location listeners, lambdas in companion object collections, MediaPlayer/ExoPlayer callbacks) require matching removal in the same diff. Example defect: TaskExecutionCallback leak in TaskService.

Activity and ReactContext must be stored as WeakReference, never strongly

Activity, ReactContext, View, or AppContext stored in a companion object, top-level object, or singleton must be a WeakReference or .weak(). Strong references cause memory leaks.

CoroutineScope lifecycle must match component lifecycle with cancel()

A GlobalScope.launch or freshly constructed CoroutineScope(...) held by a module, view, or shared object requires a matching cancel() in OnDestroy, OnViewDestroys, or sharedObjectDidRelease. The scope must be deliberately tied to process or release/reload lifetime, not just the component. Comments claiming work must outlive teardown are author-controlled and non-authoritative.

Concurrent AsyncFunction invocation must handle reentrancy

An AsyncFunction implementation that assumes only one invocation in flight (shared prompt, single callback slot, non-reentrant SDK) must guard against concurrent invocation. State what the second caller sees.

Stale state after lifecycle transitions must be invalidated

Cached sizes, layouts, or measurements must be invalidated on keyboard dismiss, rotation, or activity recreation. Example defect: stale shadow node size after keyboard dismiss.

Resume paths must not restart work that was never started

An onHostResume that unconditionally restarts every watcher, including ones the caller never subscribed to, needs the same initialization guard the others have. Resume and restore paths must not start work that was never running.

Validation order must be consistent across sibling methods

When sibling methods in the same class validate in the same order (e.g., validateType() before validatePermission()), a new method skipping validateType() throws the wrong exception (raw FileNotFoundException instead of the class's own InvalidTypeFileException).

Research platform API claims before asserting them

Before reporting a platform API guarantee, API level, or SDK behavior, verify it in this order: 1) React Native's vendored source (react-native-lab/react-native/packages/react-native/ReactAndroid/src/main/java/com/facebook/react), 2) a sibling Expo package already calling the same API, 3) expo-modules-core's own DSL definitions, 4) the package's android/build.gradle, AndroidManifest.xml, and proguard-rules.pro. Do not upgrade a guess into a finding. If unverifiable, report at lower confidence with the specific question named, or list it as an uncertainty with exactly what would resolve it.

Give your agent this brain