clojure/clojure · error · IllegalArgumentException
Missing argument
Error message
Missing argument
What it means
Clojure's cl-format implementation in RT.doFormat processes the ~a (aesthetic) directive by consuming the next argument from the remaining args list. If the format string contains ~a but the argument list is exhausted (args == null), it throws IllegalArgumentException("Missing argument").
Solutions
- Provide one argument per directive in the format string.
- Count directives (~a, ~s, etc.) in the format string and verify (count args) matches before calling format.
- Simplify or correct the format string (remove stray ~a).
- Catch IllegalArgumentException around format calls with user-supplied templates.
Example fix
;; before (format "~a and ~a" "x") ;; Missing argument ;; after (format "~a and ~a" "x" "y")
Defensive patterns
Strategy: validation
Validate before calling
(defn arg-count-ok? [fmt args] (>= (count args) (count (re-seq #"~[as]" fmt))))
Try / catch
(try (apply format fmt args)
(catch IllegalArgumentException e
(throw (ex-info "format template/argument mismatch" {:fmt fmt} (ex-cause e))))) Prevention
- Keep format strings and argument lists in sync
- Count ~a/~s directives before calling format
- Avoid building format templates dynamically from user input
- Prefer str/interp for simple substitutions
When it happens
Trigger: Calling (format "~a~a" "only-one-arg") — a format string with more directives (~a, and analogously ~s) than supplied arguments.
Common situations: Format strings edited after the argument list changed, dynamic format strings built from user config whose directive count doesn't match the values passed, porting CL format templates.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Missing ~}
- Unsupported ~ directive:
- AbortException
- Accessor/struct mismatch
- Agent does not need a restart
AI-assisted analysis of clojure/clojure@f3b143341d (2026-09-09).
Data as JSON: /api/errors/7da22613dc7ffd00.
Report an issue: GitHub.
Appendix: source
Thrown at src/jvm/clojure/lang/RT.java:2108
return null;
}
static public ISeq doFormat(Writer w, String s, ISeq args) throws IOException{
for(int i = 0; i < s.length();) {
char c = s.charAt(i++);
switch(Character.toLowerCase(c)) {
case '~':
char d = s.charAt(i++);
switch(Character.toLowerCase(d)) {
case '%':
w.write('\n');
break;
case 't':
w.write('\t');
break;
case 'a':
if(args == null)
throw new IllegalArgumentException("Missing argument");
RT.formatAesthetic(w, RT.first(args));
args = RT.next(args);
break;
case 's':
if(args == null)
throw new IllegalArgumentException("Missing argument");
RT.formatStandard(w, RT.first(args));
args = RT.next(args);
break;
case '{':
int j = s.indexOf("~}", i); //note - does not nest
if(j == -1)
throw new IllegalArgumentException("Missing ~}");
String subs = s.substring(i, j);
for(ISeq sargs = RT.seq(RT.first(args)); sargs != null;)
sargs = doFormat(w, subs, sargs);
args = RT.next(args);
i = j + 2; //skip ~}View on GitHub (pinned to f3b143341d)