TheAlgorithms/Java · error · IllegalArgumentException

State must be a non-null array of length 2.

Error message

State must be a non-null array of length 2.

What it means

Thrown by DampedOscillator.stepEuler when the state array is null or its length is not exactly 2. The explicit Euler step expects a 2-element state vector [x, v] (displacement, velocity); any other shape would cause an ArrayIndexOutOfBoundsException or a NullPointerException on state[0]/state[1]. This is the first of two guards in stepEuler (the second validates dt).

Source

Thrown at src/main/java/com/thealgorithms/physics/DampedOscillator.java:84

     * @return the displacement x(t)
     */
    public double displacementAnalytical(double amplitude, double phase, double time) {
        double omegaD = Math.sqrt(Math.max(0.0, omega0 * omega0 - gamma * gamma));
        return amplitude * Math.exp(-gamma * time) * Math.cos(omegaD * time + phase);
    }

    /**
     * Performs a single integration step using the explicit Euler method.
     * State vector format: [x, v], where v = dx/dt.
     *
     * @param state the current state [x, v]
     * @param dt    the time step (seconds)
     * @return the next state [x_next, v_next]
     * @throws IllegalArgumentException if the state array is invalid or dt is non-positive
     */
    public double[] stepEuler(double[] state, double dt) {
        if (state == null || state.length != 2) {
            throw new IllegalArgumentException("State must be a non-null array of length 2.");
        }
        if (dt <= 0) {
            throw new IllegalArgumentException("Time step must be positive.");
        }

        double x = state[0];
        double v = state[1];
        double acceleration = -2.0 * gamma * v - omega0 * omega0 * x;

        double xNext = x + dt * v;
        double vNext = v + dt * acceleration;

        return new double[] {xNext, vNext};
    }

    /** @return the natural (undamped) angular frequency (rad/s). */
    public double getOmega0() {
        return omega0;

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Always pass a 2-element double[] of the form [displacement, velocity].
  2. If you maintain a longer state elsewhere (e.g. for other physics), copy the relevant [x, v] slice into a length-2 array before stepping.
  3. Initialize state with new double[]{0.0, 0.0} at the start of a simulation rather than leaving it null.

Example fix

// before
double[] state = new double[]{1.0};
double[] next = osc.stepEuler(state, 0.01);
// after
double[] state = new double[]{1.0, 0.0};
double[] next = osc.stepEuler(state, 0.01);
Defensive patterns

Strategy: type-guard

Validate before calling

double[] state = (s == null || s.length != 2) ? new double[]{0.0, 0.0} : s;
double[] next = osc.stepEuler(state, dt);

Type guard

static boolean isValidEulerState(double[] s) {
    return s != null && s.length == 2;
}

Prevention

When it happens

Trigger: Calling stepEuler(null, dt), stepEuler(new double[]{x}, dt) (length 1), stepEuler(new double[]{x, v, a}, dt) (length 3), or passing a state array from a different integrator that uses a different state layout.

Common situations: Mixing state representations across integrators (e.g. passing a 4-element RK state to the Euler step), reusing an array that was truncated, or a null state after a failed initialization loop.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/7d09362f13dd1ff1. Report an issue: GitHub.