🔴 The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOGjava.util.NoSuchElementException: No line found at java.base/java.util.Scanner.nextLine(Scanner.java:1690)

⚡ Quick Fix Works 80% of the time

Check hasNextLine() before every nextLine() call.

if (scanner.hasNextLine()) { String line = scanner.nextLine(); handle(line); }

🧠 Why this Happens

Tap to expand the deep technical explanation

Scanner buffers chunks of its source and scans ahead looking for line terminators. At end of input there is no terminator left, so nextLine() cannot honor its contract of returning a line minus terminator and calls Scanner.throwFor, raising NoSuchElementException with detail "No line found". If the underlying stream was closed earlier you get a plain message-less NoSuchElementException instead: different wording, same root cause of reading past a dead source.

The HITEC City Parking Spot Analogy:

Pressing the button on a vending machine after it sold out: the mechanism still works, but inventory is zero.

🔁 How to Reproduce Confirm this is your error

Scanner sc = new Scanner(""); sc.nextLine(); // throws immediately - the input has zero lines

🛠️ Solutions (5 Ways to Fix)

Solution 1✓ Most common cause

Guard with hasNextLine()

👉 Use this if you must keep streaming reads from a Scanner.

hasNextLine() blocks until a line is available or EOF is confirmed, letting the loop exit normally instead of throwing mid-read.

while (scanner.hasNextLine()) { parse(scanner.nextLine()); }
Solution 2

Read the whole input once, then index safely

👉 Use this if the input fits memory and multiple passes or random access are needed.

Files.readAllLines returns a List whose size you can check; missing records become index/logic errors you control rather than scanner exceptions.

List<String> lines = Files.readAllLines(Path.of("input.txt")); for (int i = 0; i < lines.size(); i++) { parse(i, lines.get(i)); }
Solution 3

Never close a shared Scanner(System.in)

👉 Use this if several classes read console input in one application.

Closing a Scanner closes its underlying System.in for the entire process; every later read then fails instantly. Own one Scanner per stream and close nothing until shutdown.

public class ConsoleIO { private static final Scanner IN = new Scanner(System.in); public static String ask(String prompt) { System.out.print(prompt); return IN.hasNextLine() ? IN.nextLine() : ""; } }
Solution 4

Switch to BufferedReader.readLine()

👉 Use this if you prefer an end-of-file convention over exceptions.

BufferedReader signals EOF by returning null, so the classic while ((line = br.readLine()) != null) loop never throws on exhaustion.

try (BufferedReader br = Files.newBufferedReader(path)) { String line; while ((line = br.readLine()) != null) { parse(line); } }
Solution 5

Validate record counts for fixed-format files

👉 Use this if the format promises a known number of records.

Read everything, compare against the expected count, and fail fast with a message naming the file and counts instead of crashing halfway through parsing.

List<String> rows = Files.readAllLines(csv); if (rows.size() != EXPECTED_ROWS) { throw new IllegalStateException("expected " + EXPECTED_ROWS + " rows, got " + rows.size()); }

📋 Version Notes

Java 8

Same wording and behavior.

Java 11+

Unchanged. Note: after nextInt() a following nextLine() returns the empty string because the pending newline counts as a line - that produces skipped-input bugs rather than this exception.

🛡️ How to Prevent This Next Time

Pair every next*() call with its hasNext*() twin. Give one component ownership of each input stream and let try-with-resources close it exactly once.