lysine-dev/retrofit · error · NullPointerException
error == null
Error message
error == null
What it means
Result.error(Throwable) is the public factory for building an error-valued Result, used by the rxjava3 adapter to deliver network failures inside a reactive stream as data. It explicitly rejects null because a Result must carry a definite error or a definite response — a null error would make the Result semantically empty and break the error()/response() accessor invariants. It throws NullPointerException ('error == null') guarded behind a ConstantConditions suppression so the check is not stripped by static analysis.
Source
Thrown at retrofit-adapters/rxjava3/src/main/java/retrofit2/adapter/rxjava3/Result.java:26
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package retrofit2.adapter.rxjava3;
import java.io.IOException;
import javax.annotation.Nullable;
import retrofit2.Response;
/** The result of executing an HTTP request. */
public final class Result<T> {
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static <T> Result<T> error(Throwable error) {
if (error == null) throw new NullPointerException("error == null");
return new Result<>(null, error);
}
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static <T> Result<T> response(Response<T> response) {
if (response == null) throw new NullPointerException("response == null");
return new Result<>(response, null);
}
private final @Nullable Response<T> response;
private final @Nullable Throwable error;
private Result(@Nullable Response<T> response, @Nullable Throwable error) {
this.response = response;
this.error = error;
}
/**View on GitHub (pinned to d0b112dad0)
Solutions
- Null-check the argument first: `if (cause != null) Result.error(cause) else ...`.
- If the call should produce a success, use Result.response(...) instead.
- Validate upstream so the throwable reference is never null (e.g. Future.get() can return a null cause on certain ExecutionException shapes).
Example fix
// before
Result<User> r = Result.error(caught);
// after
if (caught == null) throw new IllegalArgumentException("cause must not be null");
Result<User> r = Result.error(caught); Defensive patterns
Strategy: validation
Validate before calling
Throwable cause = resolveCause();
if (cause == null) throw new IllegalArgumentException("cause required");
Result<User> result = Result.error(cause); Try / catch
try {
Result<User> r = Result.error(cause);
} catch (NullPointerException e) {
// cause was null; supply a fallback or rethrow with context
throw new IllegalArgumentException("Result.error requires a non-null cause", e);
} Prevention
- Wrap nullable throwables with Objects.requireNonNull(cause, "cause") before calling Result.error.
- Prefer Optional/onError paths over manually constructing error Results.
- In tests, never pass null to Result.error; use a real Exception instance.
When it happens
Trigger: Calling Result.error(null) — most often inside a custom Operator/Transformer that re-wraps a caught Throwable reference that resolved to null, or in test/mocking code. Thrown immediately at the top of Result.error(Throwable).
Common situations: Writing custom RxJava operators that wrap caught exceptions; mock/test setup; defensive catch blocks where the throwable variable is unexpectedly null; Future.get() wrapping where the cause is null.
Related errors
AI-assisted analysis of lysine-dev/retrofit@d0b112dad0 (2026-08-13).
Data as JSON: /api/errors/97fe9698a7dd5d05.
Report an issue: GitHub.