clojure/clojure · error · IllegalArgumentException

Error - no matches found for

Error message

Error - no matches found for ${kind != MethodKind.CTOR ? kind.toString().toLowerCase() + " " : ""}${methodDescription(c, methodName)}

What it means

The Java compiler's reflection-based method resolution collects candidate methods or constructors matching a name and MethodKind. When the candidate list is empty — no constructor exists, or no method overloads with that name/kind match — it throws this descriptive RuntimeException via noMethodWithNameException.

Solutions

  1. Check the class for the exact method/constructor name and arity via (clojure.reflect/reflect ClassName) or javap
  2. Fix static/instance call syntax: (ClassName/method args) for static, (. obj method args) for instance
  3. If a dependency upgrade removed the member, pin the old version or migrate to the replacement API
  4. Add type hints so reflection resolves to the intended class with the expected members
  5. Verify the argument types/arities match an existing overload

Example fix

// before: String has no zero-arg static valueOf(String)
(String/valueOf) ; or wrong kind/arity => no matches
// after
(String/valueOf "x") ; matches existing overload
Defensive patterns

Strategy: validation

Validate before calling

(defn member-exists? [c name]
  (some #(= name (str (:name %)))
        (concat (:members (clojure.reflect/reflect c))
                (:members (clojure.reflect/reflect c :authorize [#.toString])))))

Try / catch

try {
  List<Executable> ms = methodsWithName(c, name, kind);
} catch (RuntimeException e) {
  if (e.getMessage().startsWith("Error - no matches found")) {
    throw new IllegalStateException("Check method name/kind/arity for " + c.getName(), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Compiling Clojure code that calls a Java constructor that does not exist for the class, or invokes a method name that has no overloads of the expected kind (instance vs static), so methodsWithName finds zero matches.

Common situations: Typos in method names in interop forms; calling static methods with instance-call syntax or vice versa; constructor arity that doesn't exist; upgrading a Java dependency where methods/constructors were removed or renamed; reflection failing to find members on the resolved class.

Related errors


AI-assisted analysis of clojure/clojure@f3b143341d (2026-09-09). Data as JSON: /api/errors/dd83cde3737f8bf8. Report an issue: GitHub.

Appendix: source

Thrown at src/jvm/clojure/lang/Compiler.java:1307

		return Arrays.stream(methods)
				.filter(m -> m.getName().equals(methodName))
				.filter(m -> {
					switch(kind) {
						case STATIC: return isStaticMethod(m);
						case INSTANCE: return isInstanceMethod(m);
						default: return false;
					}
				})
				.collect(Collectors.toList());
	}

	// Returns a list of methods or ctors matching the name and kind given.
	// Otherwise, will throw if the information provided results in no matches
	private static List<Executable> methodsWithName(Class c, String methodName, MethodKind kind) {
		if (kind == MethodKind.CTOR) {
			List<Executable> ctors = Arrays.asList(c.getConstructors());
			if(ctors.isEmpty())
				throw noMethodWithNameException(c, methodName, kind);
			return ctors;
		}

		List<Executable> res = methodOverloads(c, methodName, kind);

		if(res.isEmpty())
			throw noMethodWithNameException(c, methodName, kind);
		return res;
	}

	static Executable resolveHintedMethod(Class c, String methodName, MethodKind kind, List<Class> hintedSig) {
		List<Executable> methods = methodsWithName(c, methodName, kind);
		final int arity = hintedSig.size();
		List<Executable> filteredMethods = methods.stream()
				.filter(m -> m.getParameterCount() == arity)
				.filter(m -> !m.isSynthetic()) // remove bridge/lambda methods
				.filter(m -> signatureMatches(hintedSig, m))
				.collect(Collectors.toList());

View on GitHub (pinned to f3b143341d)