{"record":{"id":"7da22613dc7ffd00","repo":"clojure/clojure","slug":"missing-argument","errorCode":null,"errorMessage":"Missing argument","messagePattern":"Missing argument","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/jvm/clojure/lang/RT.java","lineNumber":2108,"sourceCode":"\treturn null;\n}\n\nstatic public ISeq doFormat(Writer w, String s, ISeq args) throws IOException{\n\tfor(int i = 0; i < s.length();) {\n\t\tchar c = s.charAt(i++);\n\t\tswitch(Character.toLowerCase(c)) {\n\t\t\tcase '~':\n\t\t\t\tchar d = s.charAt(i++);\n\t\t\t\tswitch(Character.toLowerCase(d)) {\n\t\t\t\t\tcase '%':\n\t\t\t\t\t\tw.write('\\n');\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 't':\n\t\t\t\t\t\tw.write('\\t');\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'a':\n\t\t\t\t\t\tif(args == null)\n\t\t\t\t\t\t\tthrow new IllegalArgumentException(\"Missing argument\");\n\t\t\t\t\t\tRT.formatAesthetic(w, RT.first(args));\n\t\t\t\t\t\targs = RT.next(args);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 's':\n\t\t\t\t\t\tif(args == null)\n\t\t\t\t\t\t\tthrow new IllegalArgumentException(\"Missing argument\");\n\t\t\t\t\t\tRT.formatStandard(w, RT.first(args));\n\t\t\t\t\t\targs = RT.next(args);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '{':\n\t\t\t\t\t\tint j = s.indexOf(\"~}\", i);    //note - does not nest\n\t\t\t\t\t\tif(j == -1)\n\t\t\t\t\t\t\tthrow new IllegalArgumentException(\"Missing ~}\");\n\t\t\t\t\t\tString subs = s.substring(i, j);\n\t\t\t\t\t\tfor(ISeq sargs = RT.seq(RT.first(args)); sargs != null;)\n\t\t\t\t\t\t\tsargs = doFormat(w, subs, sargs);\n\t\t\t\t\t\targs = RT.next(args);\n\t\t\t\t\t\ti = j + 2; //skip ~}","sourceCodeStart":2090,"sourceCodeEnd":2126,"githubUrl":"https://github.com/clojure/clojure/blob/f3b143341d6efc6428b523b2eaa099a6cc99156e/src/jvm/clojure/lang/RT.java#L2090-L2126","documentation":"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\").","triggerScenarios":"Calling (format \"~a~a\" \"only-one-arg\") — a format string with more directives (~a, and analogously ~s) than supplied arguments.","commonSituations":"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.","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."],"exampleFix":";; before\n(format \"~a and ~a\" \"x\") ;; Missing argument\n;; after\n(format \"~a and ~a\" \"x\" \"y\")","handlingStrategy":"validation","validationCode":"(defn arg-count-ok? [fmt args]\n  (>= (count args) (count (re-seq #\"~[as]\" fmt))))","typeGuard":null,"tryCatchPattern":"(try (apply format fmt args)\n  (catch IllegalArgumentException e\n    (throw (ex-info \"format template/argument mismatch\" {:fmt fmt} (ex-cause e)))))","preventionTips":["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"],"tags":["clojure","format","cl-format"],"backgroundTag":"missing-required-argument","analyzedSha":"f3b143341d6efc6428b523b2eaa099a6cc99156e","analyzedAt":"2026-09-09T12:04:58.961Z","contentChangedAt":"2026-09-09T12:04:58.961Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}