{"record":{"id":"8cad00f66b12fc8b","repo":"clojure/clojure","slug":"can-t-pop-empty-vector","errorCode":null,"errorMessage":"Can't pop empty vector","messagePattern":"Can't pop empty vector","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/jvm/clojure/lang/PersistentVector.java","lineNumber":620,"sourceCode":"//\t\telse\n//\t\t\tnewchild = expansion.val;\n//\t\t}\n//\t//expansion\n//\tif(arr.length == 32)\n//\t\t{\n//\t\texpansion.val = new Object[]{newchild};\n//\t\treturn arr;\n//\t\t}\n//\tObject[] ret = new Object[arr.length + 1];\n//\tSystem.arraycopy(arr, 0, ret, 0, arr.length);\n//\tret[arr.length] = newchild;\n//\texpansion.val = null;\n//\treturn ret;\n//}\n\npublic PersistentVector pop(){\n\tif(cnt == 0)\n\t\tthrow new IllegalStateException(\"Can't pop empty vector\");\n\tif(cnt == 1)\n\t\treturn EMPTY.withMeta(meta());\n\t//if(tail.length > 1)\n\tif(cnt-tailoff() > 1)\n\t\t{\n\t\tObject[] newTail = new Object[tail.length - 1];\n\t\tSystem.arraycopy(tail, 0, newTail, 0, newTail.length);\n\t\treturn new PersistentVector(meta(), cnt - 1, shift, root, newTail);\n\t\t}\n\tObject[] newtail = arrayFor(cnt - 2);\n\n\tNode newroot = popTail(shift, root);\n\tint newshift = shift;\n\tif(newroot == null)\n\t\t{\n\t\tnewroot = EMPTY_NODE;\n\t\t}\n\tif(shift > 5 && newroot.array[1] == null)","sourceCodeStart":602,"sourceCodeEnd":638,"githubUrl":"https://github.com/clojure/clojure/blob/f3b143341d6efc6428b523b2eaa099a6cc99156e/src/jvm/clojure/lang/PersistentVector.java#L602-L638","documentation":"pop() on a PersistentVector with zero elements throws IllegalStateException(\"Can't pop empty vector\"). Popping an empty vector has no meaningful persistent value, so Clojure raises instead of returning EMPTY.","triggerScenarios":"(pop []) or .pop() when count is 0 — typically popping in a loop without checking emptiness, or a stack-like algorithm that pops more than it pushed.","commonSituations":"Stack algorithms (DFS, balanced-bracket parsers) where pops outnumber pushes, reducing a vector with pop until empty then one pop too many, mis-sequenced conj/pop pairs.","solutions":["Check (seq v) or (not (empty? v)) before pop","Use (peek v) to test/inspect without removing","Return EMPTY ([]) explicitly when the vector is empty instead of popping","Fix the push/pop balance in the algorithm"],"exampleFix":"// before\n(def v' (pop v))\n// after\n(def v' (if (seq v) (pop v) v))","handlingStrategy":"validation","validationCode":"// clojure\n(defn pop-safe [v] (if (seq v) (pop v) v))","typeGuard":"(defn poppable? [v] (and (vector? v) (seq v)))","tryCatchPattern":"(try (pop v)\n  (catch IllegalStateException _ []))","preventionTips":["Check (seq v) before pop","Use peek to inspect the top without removing","Audit push/pop pairing in stack-style algorithms"],"tags":["illegal-state","empty-collection","pop"],"backgroundTag":"invalid-state-transition","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"}