junit-team/junit5 · error · ArgumentAccessException

Argument at index [ ] with value [ ] and type [ ] could not…

Error message

Argument at index [%d] with value [%s] and type [%s] could not be converted or cast to type [%s].

What it means

Thrown by DefaultArgumentsAccessor.get(int index, Class<T> requiredType) when the value at the given index cannot be converted to the requested type via the DefaultArgumentConverter, or the converted value fails a Class.cast(). The message includes the index, the actual value (toString), its type, and the target type. The original conversion exception is attached as the cause.

Solutions

  1. Check the actual value and type shown in the error message against the requested type to identify the mismatch
  2. Ensure the CSV/source data in the failing row matches the expected type, or add null/empty checks
  3. Use a custom ArgumentConverter via @ConvertWith to handle non-standard conversions
  4. Verify the index used in accessor.getX(index) matches the actual column order in the source data

Example fix

// before — accessor type mismatch on CSV data
@ParameterizedTest
@CsvSource({ "name,abc", "age,xyz" })
void test(String label, @AggregateWith(MyAggregator.class) Data data) { }

// In aggregator: accessor.getInteger(1) on "abc" → error
// after — validate before converting or fix the source data
@ParameterizedTest
@CsvSource({ "name,42", "age,99" })
void test(String label, @AggregateWith(MyAggregator.class) Data data) { }

// Or in the aggregator, handle the type gracefully:
Object raw = accessor.get(1);
int value = (raw instanceof Number n) ? n.intValue() : Integer.parseInt(raw.toString());
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate argument type before calling accessor.getX(index)
import org.junit.jupiter.params.aggregator.ArgumentsAccessor;

static Integer safeGetInteger(ArgumentsAccessor accessor, int index) {
    Object value = accessor.get(index);
    if (value == null) return null;
    if (value instanceof Number n) return n.intValue();
    if (value instanceof String s) {
        try { return Integer.parseInt(s.trim()); }
        catch (NumberFormatException e) { return null; }
    }
    return null;
}

Type guard

// Type guard for checking if an accessor value can be safely cast
static boolean isConvertibleTo(ArgumentsAccessor accessor, int index, Class<?> target) {
    Object value = accessor.get(index);
    if (value == null) return !target.isPrimitive();
    if (target.isInstance(value)) return true;
    if (value instanceof String s) {
        try { DefaultArgumentConverter.INSTANCE.convert(s, target, ClassLoader.getSystemClassLoader()); return true; }
        catch (Exception e) { return false; }
    }
    return false;
}

Try / catch

// Wrap accessor type access in try-catch for robust error handling
try {
    int value = accessor.getInteger(1);
} catch (ArgumentAccessException e) {
    // Log the index, value, and expected type from the error message
    logger.warning("Failed to get integer at index 1: " + e.getMessage());
    // Use a default or skip this invocation
    org.junit.jupiter.api.Assumptions.assumeTrue(false, "Skipping: invalid argument at index 1");
}

Prevention

When it happens

Trigger: Call accessor.getInteger(0) on a CSV row where the first column is a non-numeric string. Call accessor.getString(0) where the value is a complex object that can't be string-converted by the built-in converter. The converter returns a type that is not assignable to requiredType, causing ClassCastException inside the cast().

Common situations: CSV-based parameterized tests where a column contains unexpected data (e.g., 'N/A' in a numeric column). Type mismatches between the declared parameter type and the actual argument value type. Index errors where the wrong column index is accessed. Argument values from custom ArgumentsProvider that aren't strings and don't match the accessor's expected type.

Related errors


AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11). Data as JSON: /api/errors/3ccf4ba0490a5116. Report an issue: GitHub.

Appendix: source

Thrown at junit-jupiter-params/src/main/java/org/junit/jupiter/params/aggregator/DefaultArgumentsAccessor.java:81

	public @Nullable Object get(int index) {
		Preconditions.condition(index >= 0 && index < this.arguments.length,
			() -> "index must be >= 0 and < %d".formatted(this.arguments.length));
		return this.arguments[index];
	}

	@Override
	public <T> @Nullable T get(int index, Class<T> requiredType) {
		Preconditions.notNull(requiredType, "requiredType must not be null");
		Object value = get(index);
		try {
			Object convertedValue = converter.apply(value, requiredType);
			return requiredType.cast(convertedValue);
		}
		catch (Exception ex) {
			String message = "Argument at index [%d] with value [%s] and type [%s] could not be converted or cast to type [%s].".formatted(
				index, value, ClassUtils.nullSafeToString(value == null ? null : value.getClass()),
				requiredType.getName());
			throw new ArgumentAccessException(message, ex);
		}
	}

	@Override
	public @Nullable Character getCharacter(int index) {
		return get(index, Character.class);
	}

	@Override
	public @Nullable Boolean getBoolean(int index) {
		return get(index, Boolean.class);
	}

	@Override
	public @Nullable Byte getByte(int index) {
		return get(index, Byte.class);
	}

View on GitHub (pinned to f070c699a0)