{"record":{"id":"580a63ac0f7192b6","repo":"google/guava","slug":"wrong-exception-thrown-from-s-when-passing-null-t","errorCode":null,"errorMessage":"wrong exception thrown from %s when passing null to %s parameter at index %s.%nFull parameters: %s%nActual exception message: %s","messagePattern":"wrong exception thrown from (.+?) when passing null to (.+?) parameter at index (.+?)\\.%nFull parameters: (.+?)%nActual exception message: (.+?)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"android/guava-testlib/src/com/google/common/testing/NullPointerTester.java","lineNumber":418,"sourceCode":"    @Nullable Object[] params = buildParamList(invokable, paramIndex);\n    try {\n      @SuppressWarnings(\"unchecked\") // We'll get a runtime exception if the type is wrong.\n      Invokable<Object, ?> unsafe = (Invokable<Object, ?>) invokable;\n      unsafe.invoke(instance, params);\n      Assert.fail(\n          \"No exception thrown for parameter at index \"\n              + paramIndex\n              + \" from \"\n              + invokable\n              + Arrays.toString(params)\n              + \" for \"\n              + testedClass);\n    } catch (InvocationTargetException e) {\n      Throwable cause = e.getCause();\n      if (policy.isExpectedType(cause)) {\n        return;\n      }\n      throw new AssertionError(\n          String.format(\n              \"wrong exception thrown from %s when passing null to %s parameter at index %s.%n\"\n                  + \"Full parameters: %s%n\"\n                  + \"Actual exception message: %s\",\n              invokable,\n              invokable.getParameters().get(paramIndex).getType(),\n              paramIndex,\n              Arrays.toString(params),\n              cause),\n          cause);\n    } catch (IllegalAccessException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  private @Nullable Object[] buildParamList(\n      Invokable<?, ?> invokable, int indexOfParamToSetToNull) {\n    ImmutableList<Parameter> params = invokable.getParameters();","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/google/guava/blob/94f39958baf7ad51ddf9c70e406ed6b188194daa/android/guava-testlib/src/com/google/common/testing/NullPointerTester.java#L400-L436","documentation":"NullPointerTester passes null to one parameter at a time (others default) and expects either NullPointerException or another exception type you have explicitly registered as acceptable. If the code under test throws a different type (e.g. IllegalArgumentException, ClassCastException, a custom RuntimeException), the test fails with this AssertionError because the null precondition is not signaled correctly.","triggerScenarios":"NullPointerTester.testEquals/testAllPublicMethods/testAllPublicConstructors on a type whose method, when a given parameter is null, throws something other than NullPointerException — e.g. Preconditions.checkArgument(cond) without a prior null check, or a field access that surfaces as a different exception.","commonSituations":"Methods guarded only by checkArgument/checkState (throw IllegalArgumentException), auto-unboxing of a null Integer, delegation to a library that throws a non-NPE, or custom validation exceptions used for null arguments.","solutions":["Add an explicit null check that throws NullPointerException: Objects.requireNonNull(param) or checkNotNull(param) at the top of the method.","If a non-NPE type is genuinely correct for that parameter, annotate the parameter @Nullable so NullPointerTester skips it.","Register the accepted exception type with tester.setDefault(Enum.class,...)/NullPointerTester policy if the API supports it, or use the per-method overload to whitelist the expected type.","Restructure the guard so checkNotNull runs before checkArgument/checkState."],"exampleFix":"// before\npublic Foo create(String name, int mode) {\n  checkArgument(mode >= 0, \"mode\"); // null name -> NPE later, wrong param\n  this.name = name.toLowerCase();\n}\n\n// after\npublic Foo create(String name, int mode) {\n  this.name = checkNotNull(name).toLowerCase();\n  checkArgument(mode >= 0, \"mode\");\n}","handlingStrategy":"validation","validationCode":"// Make null-safety explicit so NullPointester sees NPE, not a wrong type.\n// Verify before running the tester that each non-@Nullable parameter is guarded:\npublic Foo create(String name, int mode) {\n  this.name = Objects.requireNonNull(name, \"name\");\n  if (mode < 0) throw new IllegalArgumentException(\"mode\");\n  ...\n}","typeGuard":"// Mark parameters that legitimately accept null so the tester skips them.\npublic Bar compute(@Nullable String hint, int x) { ... }","tryCatchPattern":"// AssertionError from NullPointerTester is a test failure; don't swallow it.\n// Fix the production null guard (preferred) or annotate @Nullable (skip).","preventionTips":["Put checkNotNull/requireNonNull before any checkArgument/checkState in every method.","Annotate genuinely nullable parameters with @Nullable so the tester skips them.","Watch for auto-unboxing of null boxed primitives — they surface as non-NPE.","Run NullPointerTester routinely so a regression to a wrong exception type fails fast."],"tags":["guava","testing","nullpointer-tester","null-check","contract"],"backgroundTag":null,"analyzedSha":"94f39958baf7ad51ddf9c70e406ed6b188194daa","analyzedAt":"2026-08-13T22:50:30.265Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}