<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Craftstack Academy Blog]]></title><description><![CDATA[Beginner-friendly coding tutorials in Python, Web, SQL and Java, with clear examples you can try yourself.]]></description><link>https://craftstack.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6ae8ba0d69fd5203cf09e797/50ea716d-604f-4d3c-b82c-d4939ea13cd7.png</url><title>Craftstack Academy Blog</title><link>https://craftstack.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 07 Nov 2026 11:28:55 GMT</lastBuildDate><atom:link href="https://craftstack.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Java: incompatible types: String cannot be converted to int, and how to fix it]]></title><description><![CDATA[nextLine() returns a String, so int hours = scanner.nextLine() won't compile. The Integer.parseInt fix, the nextInt() trap and related errors.]]></description><link>https://craftstack.hashnode.dev/java-incompatible-types-string-cannot-be-converted-to-int</link><guid isPermaLink="true">https://craftstack.hashnode.dev/java-incompatible-types-string-cannot-be-converted-to-int</guid><category><![CDATA[Java]]></category><category><![CDATA[debugging]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[learn coding]]></category><dc:creator><![CDATA[Craftstack Academy]]></dc:creator><pubDate>Fri, 06 Nov 2026 10:13:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae8ba0d69fd5203cf09e797/417406af-678b-497d-b6b0-bcd164444e1d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You press compile, and before your program even starts, Java refuses:</p>
<pre><code class="language-plaintext">Main.java:7: error: incompatible types: String cannot be converted to int
        int hours = scanner.nextLine();
                                    ^
1 error
</code></pre>
<p>The good news: this is a <strong>compile error</strong>. Java found the problem before running anything, and it tells you the exact file, line and spot. Here's what it means, the usual causes, how to fix each one, and the related errors you're likely to meet next.</p>
<h2>What the error means</h2>
<ul>
<li><code>Main.java:7</code>: the file and the line number.</li>
<li><code>incompatible types</code>: you put a value of one type into a place meant for another type.</li>
<li><code>String cannot be converted to int</code>: the value is a <code>String</code> (text), and the place, here the variable <code>hours</code>, is an <code>int</code> (a whole number). Java won't turn one into the other on its own.</li>
</ul>
<p>The <code>^</code> mark shows where Java noticed it: at the end of <code>scanner.nextLine()</code>, the expression that produced the text.</p>
<p>Java checks types very strictly. A variable declared as <code>int</code> can only ever hold a whole number, so Java stops you as soon as you try to put text in it.</p>
<h3>The same error with java.lang.String</h3>
<p>Depending on your editor, the same message can look a little different, for example:</p>
<pre><code class="language-plaintext">java: incompatible types: java.lang.String cannot be converted to int
</code></pre>
<p><code>java.lang.String</code> is simply the full name of <code>String</code> (the class lives in the package <code>java.lang</code>), and the <code>java:</code> at the start only says that the message comes from the Java compiler. It's the same error, with the same causes and the same fixes.</p>
<h2>Cause 1: reading a number with nextLine()</h2>
<p>This is the most common one. You ask a question with a <code>Scanner</code> and want the answer as a number:</p>
<pre><code class="language-java">import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("How many hours a day are you on your phone? ");
        int hours = scanner.nextLine();
        System.out.println("That is " + hours * 365 + " hours a year.");
    }
}
</code></pre>
<p><code>scanner.nextLine()</code> always gives back the whole line the user typed as a <code>String</code>, even if they typed only digits like <code>3</code>. The text <code>"3"</code> isn't the number <code>3</code>, so it can't go into an <code>int</code>. The same goes for <code>scanner.next()</code>, which reads one word: it also gives back a <code>String</code>.</p>
<h3>The fix: Integer.parseInt</h3>
<p>Read the line as text, then convert it with <code>Integer.parseInt</code>:</p>
<pre><code class="language-java">import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("How many hours a day are you on your phone? ");
        int hours = Integer.parseInt(scanner.nextLine());
        System.out.println("That is " + hours * 365 + " hours a year.");
    }
}
</code></pre>
<pre><code class="language-plaintext">How many hours a day are you on your phone? 3
That is 1095 hours a year.
</code></pre>
<p>Read it from the inside out: <code>nextLine()</code> gives the text <code>"3"</code>, <code>Integer.parseInt</code> turns it into the number <code>3</code>, and that number goes into <code>hours</code>.</p>
<h3>What about nextInt()?</h3>
<p><code>Scanner</code> also has <code>nextInt()</code>, which reads a number directly, so it seems like the simpler fix. It works, but it has a trap that catches almost everyone. Ask for a number with <code>nextInt()</code> and then for a name with <code>nextLine()</code>:</p>
<pre><code class="language-java">import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Hours a day? ");
        int hours = scanner.nextInt();
        System.out.print("Your name? ");
        String name = scanner.nextLine();
        System.out.println("Name: [" + name + "], hours: " + hours);
    }
}
</code></pre>
<p>Type <code>3</code>, press Enter, and the program doesn't wait for your name at all:</p>
<pre><code class="language-plaintext">Hours a day? 3
Your name? Name: [], hours: 3
</code></pre>
<p><code>nextInt()</code> reads the <code>3</code> but leaves the Enter you pressed behind. The next <code>nextLine()</code> finds that leftover line break straight away and returns an empty line. That's why reading every answer with <code>nextLine()</code> and converting with <code>Integer.parseInt</code> is the safer habit. (If you do use <code>nextInt()</code>, call <code>scanner.nextLine();</code> once right after it to throw away the rest of the line.)</p>
<h2>Cause 2: a value in quotes</h2>
<p>The same error appears when you write a value in double quotes by mistake. Anything in double quotes is a <code>String</code>:</p>
<pre><code class="language-java">int age = "thirty";
</code></pre>
<pre><code class="language-plaintext">Main.java:3: error: incompatible types: String cannot be converted to int
        int age = "thirty";
                  ^
1 error
</code></pre>
<p>Here the <code>^</code> points at the text itself. The fix depends on what you meant: a number goes without quotes, <code>int age = 30;</code>, and if you really want text, the variable must be a <code>String</code>: <code>String age = "thirty";</code>.</p>
<h2>Cause 3: a method that returns a String</h2>
<p>A method's return type decides what its result is, wherever you use it. If a method is declared to return a <code>String</code>, you can't put its result into an <code>int</code>:</p>
<pre><code class="language-java">public class Main {
    static String askName() {
        return "Lena";
    }

    public static void main(String[] args) {
        int count = askName();
    }
}
</code></pre>
<pre><code class="language-plaintext">Main.java:7: error: incompatible types: String cannot be converted to int
        int count = askName();
                           ^
1 error
</code></pre>
<p>Look at the method's first line, <code>static String askName()</code>: the <code>String</code> before the name is what it gives back. Either store the result in a <code>String</code>, or, if the method should really give a number, change its return type and what it returns.</p>
<h2>What can happen next: NumberFormatException</h2>
<p>Once the program compiles, try typing <code>2.5</code> as the answer:</p>
<pre><code class="language-plaintext">How many hours a day are you on your phone? 2.5
Exception in thread "main" java.lang.NumberFormatException: For input string: "2.5"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
	at java.base/java.lang.Integer.parseInt(Integer.java:668)
	at java.base/java.lang.Integer.parseInt(Integer.java:786)
	at Main.main(Main.java:7)
</code></pre>
<p>This is a different kind of problem. The code compiled fine, but while running, <code>Integer.parseInt</code> got text that isn't a whole number. That's called an <strong>exception</strong>, and the last <code>at</code> line shows where it came from in your code: <code>Main.java:7</code>.</p>
<p>You have two options:</p>
<ul>
<li>If decimals are allowed, use a <code>double</code> and <code>Double.parseDouble</code> instead.</li>
<li>If you need a whole number, catch the exception and ask nicely:</li>
</ul>
<pre><code class="language-java">import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("How many hours a day are you on your phone? ");
        String text = scanner.nextLine();
        try {
            int hours = Integer.parseInt(text);
            System.out.println("That is " + hours * 365 + " hours a year.");
        } catch (NumberFormatException e) {
            System.out.println("Please type a whole number, like 3.");
        }
    }
}
</code></pre>
<pre><code class="language-plaintext">How many hours a day are you on your phone? 2.5
Please type a whole number, like 3.
</code></pre>
<h2>Related errors</h2>
<p>The same "incompatible types" message comes in a few other flavours. Each one names the two types, so read them the same way: the value's type first, then the type of the place it's going.</p>
<h3>int cannot be converted to String</h3>
<p>The opposite direction:</p>
<pre><code class="language-java">int hours = 3;
String label = hours;
</code></pre>
<pre><code class="language-plaintext">Main.java:4: error: incompatible types: int cannot be converted to String
        String label = hours;
                       ^
1 error
</code></pre>
<p>Turn the number into text with <code>String.valueOf(hours)</code>, or join it to some text with <code>+</code>, which makes the whole thing a <code>String</code>:</p>
<pre><code class="language-java">String label = String.valueOf(hours);   // "3"
String sentence = "Hours: " + hours;    // "Hours: 3"
</code></pre>
<h3>String cannot be converted to double</h3>
<p>The same problem with a decimal number, for example <code>double price = scanner.nextLine();</code>. The fix is the decimal version of <code>parseInt</code>:</p>
<pre><code class="language-java">double price = Double.parseDouble(scanner.nextLine());
</code></pre>
<h3>String cannot be converted to char</h3>
<pre><code class="language-java">char grade = "A";
</code></pre>
<pre><code class="language-plaintext">Main.java:3: error: incompatible types: String cannot be converted to char
        char grade = "A";
                     ^
1 error
</code></pre>
<p>In Java, double quotes make a <code>String</code>, and single quotes make a single character, a <code>char</code>. Write <code>char grade = 'A';</code>. If you have a <code>String</code> and want its first character, use <code>text.charAt(0)</code>.</p>
<h3>possible lossy conversion from double to int</h3>
<pre><code class="language-java">int total = 7;
int average = total / 2.0;
</code></pre>
<pre><code class="language-plaintext">Main.java:4: error: incompatible types: possible lossy conversion from double to int
        int average = total / 2.0;
                            ^
1 error
</code></pre>
<p><code>7 / 2.0</code> is <code>3.5</code>, a <code>double</code>, and putting it into an <code>int</code> would lose the <code>.5</code>. Java won't do that silently. Either keep the decimals with <code>double average = total / 2.0;</code>, or say that you really want to cut them off with a cast: <code>int average = (int) (total / 2.0);</code>, which gives <code>3</code>.</p>
<h2>Compile errors and exceptions</h2>
<p>It helps to keep the two apart:</p>
<ul>
<li>A <strong>compile error</strong> like <code>incompatible types</code> stops <code>javac</code> before anything runs. It always has <code>error:</code> and a line number in your file.</li>
<li>An <strong>exception</strong> like <code>NumberFormatException</code> happens while the program runs, often because of the input. It starts with <code>Exception in thread "main"</code>.</li>
</ul>
<p>Both point you to a line in your code. Start there. For the exception you'll probably meet soon after this one, see <a href="https://craftstackacademy.com/blog/java-nullpointerexception-cannot-invoke-because-is-null">Java NullPointerException</a>. And if you also write Python, it has its own version of this mix-up: <a href="https://craftstack.hashnode.dev/python-typeerror-unsupported-operand-int-and-str">Python TypeError: unsupported operand type(s) for -: 'int' and 'str'</a>.</p>
<h2>A quick checklist</h2>
<ol>
<li>Read the two types in the message: the first is the value you have, the second is what the variable (or parameter) expects.</li>
<li>Find where the value comes from: <code>nextLine()</code> and <code>next()</code> always give a <code>String</code>, so does anything in double quotes, and so does a method declared to return <code>String</code>.</li>
<li>Convert on purpose: <code>Integer.parseInt</code> or <code>Double.parseDouble</code> for text to numbers, <code>String.valueOf</code> for numbers to text, single quotes for a <code>char</code>.</li>
<li>Prefer <code>nextLine()</code> plus <code>parseInt</code> over <code>nextInt()</code>, or clear the line after <code>nextInt()</code>.</li>
<li>Once it compiles, test with input you didn't expect, like <code>2.5</code> or a word, and handle the <code>NumberFormatException</code>.</li>
</ol>
<p>The same way of reading errors works in other languages too: <a href="https://craftstack.hashnode.dev/how-to-read-an-error-message-a-3-step-method-for-python-java-javascript-and-sql">How to Read an Error Message: A 3-Step Method for Python, Java, JavaScript and SQL</a>.</p>
<p>This error is part of our free Java trial, "Your Year on Screen": you read an answer with <code>scanner.nextLine()</code> into an <code>int</code>, and the compiler stops you. The AI tutor doesn't hand you <code>Integer.parseInt</code>. It first asks you to read the error and say which two types it talks about, and gives the next hint only if you need it. One free 20-minute session, nothing to install: <a href="https://craftstackacademy.com/trial">craftstackacademy.com/trial</a>.</p>
<p><em>This article was first published on the <a href="https://craftstackacademy.com/blog/java-incompatible-types-string-cannot-be-converted-to-int">Craftstack Academy blog</a>.</em></p>
]]></content:encoded></item><item><title><![CDATA[Python TypeError: unsupported operand type(s) for -: 'int' and 'str' (or 'str' and 'int')]]></title><description><![CDATA[input() returns text, so 2026 - year fails. Why Python raises this TypeError, the int() fix, and related errors, with examples.]]></description><link>https://craftstack.hashnode.dev/python-typeerror-unsupported-operand-int-and-str</link><guid isPermaLink="true">https://craftstack.hashnode.dev/python-typeerror-unsupported-operand-int-and-str</guid><category><![CDATA[Python]]></category><category><![CDATA[python beginner]]></category><category><![CDATA[debugging]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Craftstack Academy]]></dc:creator><pubDate>Thu, 05 Nov 2026 14:27:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae8ba0d69fd5203cf09e797/4136e35f-1402-4d5f-96cf-fd53a0c6f3f7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You wrote a short program that asks for your birth year and works out your age. You type 2002, press Enter, and Python stops with this:</p>
<pre><code>Traceback (most recent call last):
  File "main.py", line 3, in &lt;module&gt;
    age = 2026 - year
          ~~~~~^~~~~~
TypeError: unsupported operand type(s) for -: 'int' and 'str'
</code></pre>
<p>This is one of the most common errors in a first Python program. The fix is one word, but it's worth understanding why it happens, because the same idea comes back again and again.</p>
<p>Here is the program:</p>
<pre><code class="language-python"># main.py
name = input("Your name? ")
year = input("Born in? ")
age = 2026 - year
print("Hi", name, "- you are", age)
</code></pre>
<h2>What the error means</h2>
<p>Read the last line of the error from the left:</p>
<ul>
<li><code>TypeError</code>: the problem is the type of a value, not its spelling.</li>
<li><code>unsupported operand type(s) for -</code>: the minus sign got values it can't work with.</li>
<li><code>'int' and 'str'</code>: the value on the left is an <code>int</code> (a whole number, 2026) and the value on the right is a <code>str</code> (a string, which means text).</li>
</ul>
<p>Python can subtract a number from a number. It can't subtract text from a number, and it doesn't guess that the text <code>"2002"</code> was meant as a number.</p>
<p>The lines above the last one tell you where it happened: line 3 of <code>main.py</code>. The <code>^</code> mark points at the minus sign. (Python 3.11 and newer draw that mark; older versions only show the line.)</p>
<h2>Why year is text</h2>
<p><code>input()</code> always gives back a string, even when you type only digits. You can check it yourself with <code>type()</code>:</p>
<pre><code class="language-python">year = input("Born in? ")
print(type(year))
</code></pre>
<pre><code>Born in? 2002
&lt;class 'str'&gt;
</code></pre>
<p>So <code>year</code> holds the text <code>"2002"</code>, not the number 2002. To Python those are as different as the word "five" and the number 5.</p>
<h2>The fix: turn the text into a number</h2>
<p>Wrap the <code>input()</code> in <code>int()</code>:</p>
<pre><code class="language-python"># main.py
name = input("Your name? ")
year = int(input("Born in? "))
age = 2026 - year
print("Hi", name, "- you are", age)
</code></pre>
<pre><code>Your name? Lena
Born in? 2002
Hi Lena - you are 24
</code></pre>
<p>Read the new line from the inside out: <code>input()</code> asks the question and gives back text, then <code>int()</code> turns that text into a whole number. Now both sides of the minus sign are numbers.</p>
<p>For numbers with a decimal point, like a height of 1.75, use <code>float()</code> instead of <code>int()</code>.</p>
<h2>The same error with other operators, and the other order</h2>
<p>The two types in the message are in the same order as in your code: the value left of the operator first, then the value right of it. So if the text is on the left, the message turns round:</p>
<pre><code class="language-python">year = "2002"
next_birthday = year - 1
</code></pre>
<pre><code>TypeError: unsupported operand type(s) for -: 'str' and 'int'
</code></pre>
<p>The symbol after <code>for</code> tells you which operator failed. With text on the left, you'll see the same message for division and floor division, and a slightly longer one for powers:</p>
<pre><code>TypeError: unsupported operand type(s) for /: 'str' and 'int'
TypeError: unsupported operand type(s) for //: 'str' and 'int'
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
</code></pre>
<p>And with a number on the left of a <code>+</code>, like <code>2026 + year</code>, it's <code>for +: 'int' and 'str'</code>. You get the same message from <code>sum()</code> on a list of strings, such as <code>sum(["72", "85"])</code>, because <code>sum</code> adds the items up one by one, starting from the number 0.</p>
<p>The fix is the same every time: convert the text to a number before you calculate, with <code>int()</code> or <code>float()</code>.</p>
<p>Three operators behave differently, so watch out for them:</p>
<ul>
<li><code>year + 1</code> with text on the left gives <code>can only concatenate str (not "int") to str</code> (see below).</li>
<li><code>year % 2</code> gives the puzzling <code>TypeError: not all arguments converted during string formatting</code>, because <code>%</code> after a string means "fill in this text", not "remainder".</li>
<li><code>year * 2</code> gives no error at all: it prints <code>20022002</code>. Multiplying text by a whole number repeats the text. (Two strings, like <code>"5" * "3"</code>, do fail: <code>can't multiply sequence by non-int of type 'str'</code>.)</li>
</ul>
<p>If the message says <code>'NoneType'</code> instead of <code>'str'</code>, the value isn't text but nothing: often a function that prints its result instead of returning it.</p>
<h2>Two errors you may meet next</h2>
<h3>can only concatenate str (not "int") to str</h3>
<p>This is the same problem the other way round. <code>+</code> between two strings joins them, but here one side is a number:</p>
<pre><code class="language-python">print("Born in " + 2002)
</code></pre>
<pre><code>TypeError: can only concatenate str (not "int") to str
</code></pre>
<p>Either let <code>print()</code> put the pieces together with commas, <code>print("Born in", 2002)</code>, or turn the number into text first with <code>str(2002)</code>.</p>
<h3>ValueError: invalid literal for int() with base 10</h3>
<p><code>int()</code> only works when the text really is a whole number. If someone types a word, the conversion fails:</p>
<pre><code>Your name? Lena
Born in? nineteen
Traceback (most recent call last):
  File "main.py", line 2, in &lt;module&gt;
    year = int(input("Born in? "))
ValueError: invalid literal for int() with base 10: 'nineteen'
</code></pre>
<p>This one isn't a mistake in your code: it's input your program didn't expect. Handling it with <code>try</code> and <code>except</code> is the topic of Error Handling in Python Course 3.</p>
<p>Another error from a first program that's worth knowing: <a href="https://craftstackacademy.com/blog/python-indentationerror-expected-an-indented-block">Python IndentationError: expected an indented block after 'if', 'for' or a function</a>. And if you're also learning Java, it has its own version of this mix-up: <a href="https://craftstackacademy.com/blog/java-incompatible-types-string-cannot-be-converted-to-int">Java: incompatible types: String cannot be converted to int</a>.</p>
<h2>How to read any TypeError</h2>
<ol>
<li>Find the line number in the traceback, and the <code>^</code> mark under the line.</li>
<li>Look at the operator or function it points to: <code>-</code>, <code>+</code>, <code>len()</code> and so on.</li>
<li>Read the two types the message names. If you're not sure which value is which, print <code>type()</code> of each.</li>
<li>Convert one side so the types match: <code>int()</code>, <code>float()</code> or <code>str()</code>.</li>
</ol>
<p>The same way of reading errors works in other languages too: <a href="https://craftstack.hashnode.dev/how-to-read-an-error-message-a-3-step-method-for-python-java-javascript-and-sql">How to Read an Error Message: A 3-Step Method for Python, Java, JavaScript and SQL</a>.</p>
<p>This exact error is part of our free Python trial, "Your Life in Numbers". When it happens, the AI tutor doesn't tell you to add <code>int()</code>. It first asks you to read the last line and say which two types it mentions, and only gives the next hint if you need it, so the fix is one you found yourself. One free 20-minute session, nothing to install: <a href="https://craftstackacademy.com/trial">craftstackacademy.com/trial</a>. It leads into our <a href="https://craftstackacademy.com/courses/python">Python course</a>.</p>
<p><em>This article was first published on the <a href="https://craftstackacademy.com/blog/python-typeerror-unsupported-operand-int-and-str">Craftstack Academy blog</a>.</em></p>
]]></content:encoded></item><item><title><![CDATA[SQLite error "no such column": usually missing quotes, plus 4 other causes]]></title><description><![CDATA[SQLite says "no such column"? Usually a text value is missing single quotes. Five causes and fixes, with examples.]]></description><link>https://craftstack.hashnode.dev/sqlite-no-such-column-error</link><guid isPermaLink="true">https://craftstack.hashnode.dev/sqlite-no-such-column-error</guid><category><![CDATA[SQL]]></category><category><![CDATA[SQLite]]></category><category><![CDATA[database]]></category><category><![CDATA[debugging]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Craftstack Academy]]></dc:creator><pubDate>Wed, 04 Nov 2026 11:38:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae8ba0d69fd5203cf09e797/df2177da-cdb2-4515-bc1f-d22101066243.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You want the visitors who went into the room called Vault, so you write:</p>
<pre><code class="language-sql">SELECT name FROM visitors WHERE room = Vault;
</code></pre>
<p>and SQLite answers:</p>
<pre><code>Error: no such column: Vault
</code></pre>
<p>But <code>Vault</code> isn't supposed to be a column. It's the value you're looking for. That's exactly the problem, and the fix is two small marks.</p>
<h2>Try it yourself</h2>
<p>Here's a tiny table to run in any SQLite tool, such as DB Browser for SQLite or the SQL editor in a Craftstack session:</p>
<pre><code class="language-sql">CREATE TABLE visitors (id INTEGER PRIMARY KEY, name TEXT, room TEXT, entered TEXT);
INSERT INTO visitors (name, room, entered) VALUES
  ('Ava Brooks', 'Lobby', '21:40'),
  ('Ben Carter', 'Vault', '22:15'),
  ('Cleo Diaz', 'Vault', '22:50'),
  ('Dan Evans', 'Cafe', '23:05');
</code></pre>
<h2>Why SQLite looks for a column</h2>
<p>Apart from SQL's own keywords like <code>SELECT</code> and <code>WHERE</code>, a word without quotes is a name: the name of a table, a column or a function. So in <code>WHERE room = Vault</code>, SQLite reads <code>Vault</code> the same way it reads <code>room</code>, as a column, and compares the two columns. There's no column called <code>Vault</code>, so it stops.</p>
<p>Text values, the actual words stored in the table, go in single quotes:</p>
<pre><code class="language-sql">SELECT name FROM visitors WHERE room = 'Vault';
</code></pre>
<pre><code>Ben Carter
Cleo Diaz
</code></pre>
<p>Numbers don't need quotes (<code>WHERE id = 2</code>), and neither do column names. Text always does.</p>
<p><strong>What about double quotes?</strong> SQLite often accepts <code>"Vault"</code> too, but only as a fallback: double quotes are meant for names, and other databases such as PostgreSQL read <code>"Vault"</code> as a column. Use single quotes for text and your queries will work everywhere.</p>
<p>The tool you use may word the start of the message differently. Python's <code>sqlite3</code> module, for example, raises <code>sqlite3.OperationalError: no such column: Vault</code>. The important part is the same: <code>no such column</code>, followed by the word SQLite couldn't find.</p>
<h2>Four other causes</h2>
<h3>A typo in a column name</h3>
<pre><code class="language-sql">SELECT nmae FROM visitors;
</code></pre>
<pre><code>Error: no such column: nmae
</code></pre>
<p>The word at the end of the message is your clue: it's exactly what you typed. Compare it with the real column names letter by letter.</p>
<h3>A column that's in another table</h3>
<pre><code class="language-sql">SELECT name, coat FROM visitors;
</code></pre>
<pre><code>Error: no such column: coat
</code></pre>
<p>Maybe <code>coat</code> exists, but in a different table. A query can only use columns from the tables in its <code>FROM</code> part. To use columns from two tables, you join them with <code>JOIN</code>, which is a topic of its own.</p>
<h3>A table alias that wasn't declared</h3>
<p>Short names for tables, like <code>v</code> for <code>visitors</code>, only exist if you declare them in the <code>FROM</code> part:</p>
<pre><code class="language-sql">SELECT v.name FROM visitors WHERE room = 'Vault';
</code></pre>
<pre><code>Error: no such column: v.name
</code></pre>
<p>Add the alias after the table name, and use it consistently:</p>
<pre><code class="language-sql">SELECT v.name FROM visitors AS v WHERE v.room = 'Vault';
</code></pre>
<h3>A column added after the table was created</h3>
<p>This one catches people who build a small app. The code starts with <code>CREATE TABLE IF NOT EXISTS</code>, and later you add a column to it:</p>
<pre><code class="language-sql">CREATE TABLE IF NOT EXISTS visitors (id INTEGER PRIMARY KEY, name TEXT, room TEXT, entered TEXT);
</code></pre>
<p>If the database file already has a <code>visitors</code> table from before, without <code>entered</code>, this line does nothing: the table exists, so it isn't created again. The next <code>SELECT entered FROM visitors</code> fails with <code>no such column: entered</code>, even though the column is right there in your code.</p>
<p>Add the column to the existing table:</p>
<pre><code class="language-sql">ALTER TABLE visitors ADD COLUMN entered TEXT;
</code></pre>
<p>Or, while you're still practising and the data doesn't matter, delete the database file (or <code>DROP TABLE visitors;</code>) and let the code create it again.</p>
<h2>Errors that look alike</h2>
<p>A few other messages come from the same kind of mix-up between names and values:</p>
<ul>
<li><strong><code>no such table: visitor</code></strong>: the same problem one level up, a misspelled table name (here <code>visitor</code> instead of <code>visitors</code>), or a table that was never created in this database file.</li>
<li><strong><code>table visitors has no column named nmae</code></strong>: what SQLite says when the misspelled column is in an <code>INSERT</code>, like <code>INSERT INTO visitors (nmae, room) VALUES ('Eve Fox', 'Lobby');</code>.</li>
<li><strong><code>ambiguous column name: name</code></strong>: the opposite problem. After a <code>JOIN</code>, two tables both have a column called <code>name</code>, and SQLite doesn't know which one you mean. Put the table name in front: <code>SELECT visitors.name, rooms.floor FROM visitors JOIN rooms ON visitors.room = rooms.name;</code>.</li>
</ul>
<p>Once you start counting and grouping rows, a different family of messages appears: <a href="https://craftstackacademy.com/blog/sql-group-by-misuse-of-aggregate-must-appear-in-group-by">SQL GROUP BY errors: "misuse of aggregate" and "must appear in the GROUP BY clause"</a>.</p>
<h2>The same error in PostgreSQL</h2>
<p>If you move to PostgreSQL, the missing quotes give <code>ERROR: column "vault" does not exist</code>. Notice the lower-case <code>vault</code>: PostgreSQL turns names without quotes into lower case, so the message doesn't even show the word exactly as you typed it. And <code>"Vault"</code> in double quotes, which SQLite quietly accepts as text, is a column name in PostgreSQL: <code>ERROR: column "Vault" does not exist</code>. Single quotes work in both.</p>
<h2>How to see which columns a table has</h2>
<p>In SQLite, <code>PRAGMA table_info</code> lists the columns of a table:</p>
<pre><code class="language-sql">PRAGMA table_info(visitors);
</code></pre>
<table>
<thead>
<tr>
<th>cid</th>
<th>name</th>
<th>type</th>
<th>notnull</th>
<th>dflt_value</th>
<th>pk</th>
</tr>
</thead>
<tbody><tr>
<td>0</td>
<td>id</td>
<td>INTEGER</td>
<td>0</td>
<td></td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>name</td>
<td>TEXT</td>
<td>0</td>
<td></td>
<td>0</td>
</tr>
<tr>
<td>2</td>
<td>room</td>
<td>TEXT</td>
<td>0</td>
<td></td>
<td>0</td>
</tr>
<tr>
<td>3</td>
<td>entered</td>
<td>TEXT</td>
<td>0</td>
<td></td>
<td>0</td>
</tr>
</tbody></table>
<p>Most tools also show the columns in a sidebar. Check the list before you go hunting for anything more complicated.</p>
<h2>A quick checklist</h2>
<ol>
<li>Read the word at the end of the message: that's what SQLite tried to use as a column.</li>
<li>Is it a value, like a room, a name or a color? Put it in single quotes.</li>
<li>Is it meant to be a column? Check the spelling against the table's columns with <code>PRAGMA table_info</code>.</li>
<li>Is the column in another table? Add that table with a <code>JOIN</code>.</li>
<li>Does it start with a short name like <code>v.</code>? Declare that alias in the <code>FROM</code> part.</li>
<li>Did you add the column to your code later? Add it to the existing table with <code>ALTER TABLE ... ADD COLUMN</code>.</li>
</ol>
<p>Once it works, you can keep adding conditions with <code>AND</code>:</p>
<pre><code class="language-sql">SELECT name FROM visitors WHERE room = 'Vault' AND entered &gt;= '22:30';
</code></pre>
<pre><code>Cleo Diaz
</code></pre>
<p>The same "read the last word" habit works for errors in other languages too: <a href="https://craftstack.hashnode.dev/how-to-read-an-error-message-a-3-step-method-for-python-java-javascript-and-sql">How to Read an Error Message: A 3-Step Method for Python, Java, JavaScript and SQL</a>.</p>
<p>New to SQL and wondering how it compares with other languages? See <a href="https://craftstackacademy.com/blog/which-programming-language-to-learn-first">Which programming language should you learn first?</a></p>
<p>Our free SQL trial, "The Museum Mystery", is built around a query just like this one: a diamond is missing from the Vault, and you narrow the visitor log down, clue by clue, to the thief. If you meet "no such column" on the way, the AI tutor lets you find the missing quotes yourself. One free 20-minute session, nothing to install: <a href="https://craftstackacademy.com/trial">craftstackacademy.com/trial</a>. It leads into our <a href="https://craftstackacademy.com/courses/sql">Databases &amp; SQL course</a>.</p>
<p><em>This article was first published on the <a href="https://craftstackacademy.com/blog/sqlite-no-such-column-error">Craftstack Academy blog</a>.</em></p>
]]></content:encoded></item><item><title><![CDATA[Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')]]></title><description><![CDATA[querySelector returned null: a missing #, a script that runs too early, or a class vs id mix-up. Four causes and fixes, with examples.]]></description><link>https://craftstack.hashnode.dev/javascript-cannot-read-properties-of-null-addeventlistener</link><guid isPermaLink="true">https://craftstack.hashnode.dev/javascript-cannot-read-properties-of-null-addeventlistener</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[webdev]]></category><category><![CDATA[debugging]]></category><category><![CDATA[frontend]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Craftstack Academy]]></dc:creator><pubDate>Tue, 03 Nov 2026 16:06:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae8ba0d69fd5203cf09e797/657de998-396d-482a-80bf-4a7843994945.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You added a button and a few lines of JavaScript to make it do something. You click it, nothing happens, and the browser console says:</p>
<pre><code>Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
</code></pre>
<p>The message sounds technical, but it says something simple: JavaScript didn't find your element. Here's how to read it, the mistakes that cause it almost every time, and a few related errors that look alike.</p>
<h2>What the error means</h2>
<p>Read it from the end:</p>
<ul>
<li><code>(reading 'addEventListener')</code>: your code tried to use <code>addEventListener</code> on something.</li>
<li><code>of null</code>: that something was <code>null</code>, which means "nothing".</li>
<li><code>Cannot read properties</code>: you can't call anything on nothing.</li>
</ul>
<p>So the variable you called <code>addEventListener</code> on is <code>null</code>. Where did it come from? Almost always from a line like this, just above:</p>
<pre><code class="language-js">// app.js
const button = document.querySelector("#color-btn");
</code></pre>
<p><code>document.querySelector</code> gives back the first element that matches the selector, or <code>null</code> if nothing on the page matches. Then the next line fails:</p>
<pre><code class="language-js">// app.js
button.addEventListener("click", () =&gt; {
  document.body.style.background = "lightyellow";
});
</code></pre>
<p>The error also stops your script at that line, so nothing written after it runs either.</p>
<h2>Cause 1: a missing # in the selector</h2>
<p><code>querySelector</code> uses CSS selectors. An id needs a <code>#</code> in front, and a class needs a <code>.</code>:</p>
<pre><code class="language-html">&lt;!-- index.html --&gt;
&lt;button id="color-btn"&gt;Change color&lt;/button&gt;
&lt;script&gt;
  const button = document.querySelector("color-btn");
  button.addEventListener("click", () =&gt; {
    document.body.style.background = "lightyellow";
  });
&lt;/script&gt;
</code></pre>
<p>Without the <code>#</code>, <code>"color-btn"</code> means "an element whose tag name is color-btn", like <code>&lt;color-btn&gt;</code>. There's no such tag on the page, so you get <code>null</code>.</p>
<p>The fix is one character:</p>
<pre><code class="language-js">const button = document.querySelector("#color-btn");
</code></pre>
<p>Or use <code>getElementById</code>, which takes the id without the <code>#</code>:</p>
<pre><code class="language-js">const button = document.getElementById("color-btn");
</code></pre>
<p>Check the spelling too: <code>color-btn</code> in the HTML and <code>colour-btn</code> in the JavaScript are different ids, and the result is the same error.</p>
<h2>Cause 2: the script runs before the element exists</h2>
<p>This version has a perfect selector and still fails:</p>
<pre><code class="language-html">&lt;!-- index.html --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;script src="app.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;button id="color-btn"&gt;Change color&lt;/button&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>The browser reads the page from top to bottom. It reaches the <code>&lt;script&gt;</code> in the <code>&lt;head&gt;</code> and runs <code>app.js</code> right away, before it has read the <code>&lt;body&gt;</code>. At that moment the button doesn't exist yet, so <code>querySelector</code> returns <code>null</code>.</p>
<p>You have three ways to fix it. Any one is enough:</p>
<ol>
<li>Move the <code>&lt;script&gt;</code> to the end of the <code>&lt;body&gt;</code>, just before <code>&lt;/body&gt;</code>.</li>
<li>Keep it in the <code>&lt;head&gt;</code> but add <code>defer</code>: <code>&lt;script src="app.js" defer&gt;&lt;/script&gt;</code>. The browser then runs it after the page has been read.</li>
<li>Wrap your code so it waits for the page:</li>
</ol>
<pre><code class="language-js">// app.js
document.addEventListener("DOMContentLoaded", () =&gt; {
  const button = document.querySelector("#color-btn");
  button.addEventListener("click", () =&gt; {
    document.body.style.background = "lightyellow";
  });
});
</code></pre>
<h2>Cause 3: an id that's really a class</h2>
<p>The selector has to use the same kind of name as the HTML. Here the button has a class, but the selector looks for an id:</p>
<pre><code class="language-html">&lt;!-- index.html --&gt;
&lt;button class="color-btn"&gt;Change color&lt;/button&gt;
&lt;script&gt;
  const button = document.querySelector("#color-btn");
  button.addEventListener("click", () =&gt; {
    document.body.style.background = "lightyellow";
  });
&lt;/script&gt;
</code></pre>
<p><code>#color-btn</code> only matches <code>id="color-btn"</code>, so <code>querySelector</code> returns <code>null</code> and you get the same error. Match the selector to the HTML: <code>".color-btn"</code> for a class, <code>"#color-btn"</code> for an id. And remember that <code>getElementById</code> only finds ids: it never finds an element by its class.</p>
<h2>Cause 4: one script, several pages</h2>
<p>Your site has a home page with the button and an About page without it, and both load the same <code>app.js</code>. On the home page everything works. On the About page, the console shows the error, and anything after that line in <code>app.js</code> doesn't run there either.</p>
<p>The script isn't wrong; the element isn't on every page. Only add the listener when the element exists:</p>
<pre><code class="language-js">// app.js
const button = document.querySelector("#color-btn");
if (button) {
  button.addEventListener("click", () =&gt; {
    document.body.style.background = "lightyellow";
  });
}
</code></pre>
<p>Or, shorter, with the <code>?.</code> operator, which skips the call when the value is <code>null</code>:</p>
<pre><code class="language-js">// app.js
button?.addEventListener("click", () =&gt; {
  document.body.style.background = "lightyellow";
});
</code></pre>
<p>Use this only when the element is really optional. If it should be on the page, a silent <code>?.</code> hides the real problem: fix the selector or the script's position instead.</p>
<h2>Errors that look alike</h2>
<h3>addEventListener is not a function</h3>
<p><code>getElementsByClassName</code> and <code>querySelectorAll</code> don't return one element, but a list of all matches. A list has no <code>addEventListener</code>, so this fails with a different message:</p>
<pre><code class="language-js">// app.js
const buttons = document.querySelectorAll(".btn");
buttons.addEventListener("click", () =&gt; {});
</code></pre>
<pre><code>Uncaught TypeError: buttons.addEventListener is not a function
</code></pre>
<p>Add the listener to each element in the list instead:</p>
<pre><code class="language-js">// app.js
const buttons = document.querySelectorAll(".btn");
buttons.forEach(button =&gt; {
  button.addEventListener("click", () =&gt; {
    console.log("clicked", button.textContent);
  });
});
</code></pre>
<h3>Cannot read properties of undefined (reading 'addEventListener')</h3>
<p><code>undefined</code> instead of <code>null</code> usually means you took an item from a list that was empty: <code>document.getElementsByClassName("btn")[0]</code> gives <code>undefined</code> when there's no element with that class. The causes and fixes are the same as above: check the class name and where the script runs.</p>
<h3>Cannot set properties of null (setting 'textContent')</h3>
<p>If you assign to the element instead of calling a method on it, like <code>document.querySelector("#total").textContent = "5";</code>, Chrome says <code>Cannot set properties of null (setting 'textContent')</code>. It's the same problem: the element wasn't found.</p>
<h3>In Firefox and Safari</h3>
<p>Other browsers word it differently. Firefox says something like <code>button is null</code>, and Safari something like <code>null is not an object (evaluating 'button.addEventListener')</code>. Whatever the wording, it means the same thing: the value before the dot is <code>null</code>.</p>
<p>If the problem is the opposite one, your styles not showing up instead of your script failing, see <a href="https://craftstackacademy.com/blog/css-not-working-why-styles-dont-apply">CSS not working? 7 reasons your styles don't apply</a>.</p>
<h2>How to find the culprit quickly</h2>
<ol>
<li>Open the console (F12 in most browsers, then the <strong>Console</strong> tab) and click the file name and line number next to the error. It takes you to the line that failed.</li>
<li>Look at the variable before the dot, here <code>button</code>, and find the line that created it.</li>
<li>Log it: <code>console.log(button);</code>. If the console shows <code>null</code>, the selector found nothing.</li>
<li>Compare the selector with the HTML: the <code>#</code> or <code>.</code>, the spelling, and whether the element is above or below your script.</li>
</ol>
<p>The same pattern explains its cousins: <code>(reading 'textContent')</code>, <code>(reading 'value')</code> or <code>(reading 'appendChild')</code> all mean that the element before the dot is <code>null</code>.</p>
<p>The same three questions (what went wrong, where, and what it asks about your code) work for errors in other languages too: <a href="https://craftstack.hashnode.dev/how-to-read-an-error-message-a-3-step-method-for-python-java-javascript-and-sql">How to Read an Error Message: A 3-Step Method for Python, Java, JavaScript and SQL</a>.</p>
<p>We checked every example in this article in Chrome, which writes the messages exactly as shown. If you're just starting with JavaScript, our guide <a href="https://craftstackacademy.com/blog/which-programming-language-to-learn-first">Which programming language should you learn first?</a> explains where it fits next to HTML and CSS.</p>
<p>In our <a href="https://craftstackacademy.com/courses/web">Web course</a>, this error is one of the first things you meet when your JavaScript starts talking to the page, and the AI tutor helps you read the console instead of guessing. You can start with the free Web trial, "Your Card on the Web": one 20-minute session where you build a profile card with HTML and CSS, with nothing to install: <a href="https://craftstackacademy.com/trial">craftstackacademy.com/trial</a>.</p>
<p><em>This article was first published on the <a href="https://craftstackacademy.com/blog/javascript-cannot-read-properties-of-null-addeventlistener">Craftstack Academy blog</a>.</em></p>
]]></content:encoded></item><item><title><![CDATA[How to Read an Error Message: A 3-Step Method for Python, Java, JavaScript and SQL]]></title><description><![CDATA[A simple method to read any error message, with real beginner examples: TypeError, IndentationError, NullPointerException, “no such column” and more.]]></description><link>https://craftstack.hashnode.dev/how-to-read-an-error-message-a-3-step-method-for-python-java-javascript-and-sql</link><guid isPermaLink="true">https://craftstack.hashnode.dev/how-to-read-an-error-message-a-3-step-method-for-python-java-javascript-and-sql</guid><category><![CDATA[Python]]></category><category><![CDATA[Java]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[SQL]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Craftstack Academy]]></dc:creator><pubDate>Tue, 03 Nov 2026 15:21:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae8ba0d69fd5203cf09e797/f24202e1-01e1-46d5-bbc7-2f9939fc36c9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every beginner meets the same moment: you press Run, the screen fills with red text, and your first instinct is to close it and stare at your code instead.</p>
<p>Don't. The error message is the most useful thing on your screen. It was written by the people who built the language, and it usually tells you <strong>what</strong> went wrong and <strong>where</strong>. You just need to know where to look.</p>
<p>Here's a 3-step method that works the same way in Python, Java, JavaScript and SQL, with the most common beginner errors in each language as examples.</p>
<h2>The 3-step method</h2>
<ol>
<li><strong>Read the last line first.</strong> That's the error type and the message: the <em>what</em>.</li>
<li><strong>Find the line number.</strong> That's the <em>where</em>. Look at that line, and if nothing is wrong there, look at the line just above it.</li>
<li><strong>Translate the message into a question about your code.</strong> "unsupported operand types <code>int</code> and <code>str</code>" becomes: <em>"Which value on this line is text when I expected a number?"</em></li>
</ol>
<p>That's it. Let's try it on real errors.</p>
<h2>Python: the error is at the bottom</h2>
<p>Here's a tiny program:</p>
<pre><code class="language-python">name = input("Your name? ")
year = input("Born in? ")
age = 2026 - year
print("Hi", name, "- you are", age)
</code></pre>
<p>Python answers with this:</p>
<pre><code class="language-plaintext">Traceback (most recent call last):
  File "life.py", line 3, in &lt;module&gt;
    age = 2026 - year
          ~~~~~^~~~~~
TypeError: unsupported operand type(s) for -: 'int' and 'str'
</code></pre>
<p><strong>Step 1, the last line:</strong> <code>TypeError: unsupported operand type(s) for -: 'int' and 'str'</code>. You tried to subtract, and one side is a number (<code>int</code>) while the other is text (<code>str</code>).</p>
<p><strong>Step 2, the line number:</strong> line 3, and newer Python versions even underline the exact spot with <code>^</code>.</p>
<p><strong>Step 3, the question:</strong> <em>which value is text?</em> <code>year</code>, because <code>input()</code> always gives you back text, even when someone types 1990. Convert it first: <code>int(year)</code>.</p>
<p>👉 Full explanation, plus the other ways this error appears: <a href="https://craftstackacademy.com/blog/python-typeerror-unsupported-operand-int-and-str">Python TypeError: unsupported operand type(s) for 'int' and 'str'</a></p>
<p>Python also has errors that stop the program before it even starts, like this one:</p>
<pre><code class="language-plaintext">  File "loop.py", line 3
    print(s)
    ^^^^^
IndentationError: expected an indented block after 'for' statement on line 2
</code></pre>
<p>Same method: the last line says <em>what</em> (Python expected an indented block), and the message even tells you <em>where</em> the problem started: the <code>for</code> on line 2. The line after it needs to be indented.</p>
<p>👉 <a href="https://craftstackacademy.com/blog/python-indentationerror-expected-an-indented-block">Python IndentationError: expected an indented block after 'if', 'for' or a function</a></p>
<h2>Java: the compiler stops you before you run</h2>
<p>Java checks your code before it runs, so many errors show up at compile time:</p>
<pre><code class="language-plaintext">Main.java:6: error: incompatible types: String cannot be converted to int
        int age = scanner.nextLine();
                                  ^
</code></pre>
<p><strong>Step 1:</strong> <em>incompatible types: String cannot be converted to int</em>. You're putting text into a box made for whole numbers.</p>
<p><strong>Step 2:</strong> <code>Main.java:6</code> means file <code>Main.java</code>, line 6. The <code>^</code> points at the value that doesn't fit.</p>
<p><strong>Step 3:</strong> <em>where does this value come from, and what type is it?</em> <code>nextLine()</code> returns a <code>String</code>. Convert it with <code>Integer.parseInt(...)</code>, or read a number directly.</p>
<p>👉 <a href="https://craftstackacademy.com/blog/java-incompatible-types-string-cannot-be-converted-to-int">Java: incompatible types: String cannot be converted to int</a></p>
<p>Java's most famous runtime error works the same way. Newer Java versions spell out exactly what was <code>null</code>:</p>
<pre><code class="language-plaintext">Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "..." is null
</code></pre>
<p>Read it as a sentence: <em>I couldn't call</em> <code>length()</code><em>, because this variable was</em> <code>null</code><em>.</em> The question to ask: <em>where should this variable have been given a value, and why wasn't it?</em></p>
<p>👉 <a href="https://craftstackacademy.com/blog/java-nullpointerexception-cannot-invoke-because-is-null">Java NullPointerException: Cannot invoke ... because ... is null</a></p>
<h2>JavaScript: open the browser console</h2>
<p>In the browser, errors don't pop up on the page. Press <strong>F12</strong> (or right-click → Inspect) and open the <strong>Console</strong> tab. One of the most common messages you'll find there:</p>
<pre><code class="language-plaintext">Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
</code></pre>
<p><strong>Step 1:</strong> you tried to use <code>.addEventListener</code> on something that is <code>null</code>, meaning <em>nothing</em>.</p>
<p><strong>Step 2:</strong> the console shows the file and line on the right. Click it to jump straight there.</p>
<p><strong>Step 3:</strong> <em>why is this element</em> <code>null</code><em>?</em> Usually <code>document.querySelector(...)</code> didn't find anything: the selector has a typo, or the script runs before the HTML element exists.</p>
<p>👉 <a href="https://craftstackacademy.com/blog/javascript-cannot-read-properties-of-null-addeventlistener">JavaScript: Cannot read properties of null (reading 'addEventListener')</a></p>
<h2>SQL: the last word is your clue</h2>
<p>Database errors are short, but they still follow the pattern:</p>
<pre><code class="language-sql">SELECT name FROM visitors WHERE room = Vault;
</code></pre>
<pre><code class="language-plaintext">Error: no such column: Vault
</code></pre>
<p><strong>Step 1:</strong> SQLite looked for a <em>column</em> called <code>Vault</code>.</p>
<p><strong>Step 2:</strong> there's only one line here, so look at the word the message names.</p>
<p><strong>Step 3:</strong> <em>is</em> <code>Vault</code> <em>meant to be a column or a value?</em> It's a value, the name of a room, so it needs single quotes: <code>WHERE room = 'Vault'</code>.</p>
<p>👉 <a href="https://craftstackacademy.com/blog/sqlite-no-such-column-error">SQLite error "no such column": usually missing quotes, plus 4 other causes</a></p>
<p>When you start counting and grouping rows, you'll meet a different kind of message, about aggregates and <code>GROUP BY</code>. The same 3 steps work:</p>
<p>👉 <a href="https://craftstackacademy.com/blog/sql-group-by-misuse-of-aggregate-must-appear-in-group-by">SQL GROUP BY errors: "misuse of aggregate" and "must appear in the GROUP BY clause"</a></p>
<h2>And when there's no error at all?</h2>
<p>The hardest bugs are the silent ones. CSS is the classic example: if a style doesn't apply, the browser doesn't complain at all. Then the method changes slightly: instead of reading a message, you <strong>inspect</strong> the element (F12 → Elements) and check which styles are crossed out and why.</p>
<p>👉 <a href="https://craftstackacademy.com/blog/css-not-working-why-styles-dont-apply">CSS not working? 7 reasons your styles don't apply</a></p>
<p>The same goes for code that runs but gives the wrong answer. No message will save you there. You compare what you <em>expected</em> with what you <em>got</em>, and work backwards.</p>
<h2>Cheat sheet</h2>
<table>
<thead>
<tr>
<th>Language</th>
<th>Where the "what" is</th>
<th>Where the "where" is</th>
</tr>
</thead>
<tbody><tr>
<td>Python</td>
<td>Last line of the traceback</td>
<td><code>File "...", line N</code> just above it</td>
</tr>
<tr>
<td>Java</td>
<td>After <code>error:</code> or <code>Exception:</code></td>
<td><code>File.java:N</code>, or the first <code>at ...</code> line of the stack trace</td>
</tr>
<tr>
<td>JavaScript</td>
<td>The red line in the browser Console</td>
<td>File and line link on the right</td>
</tr>
<tr>
<td>SQL</td>
<td>The message itself, especially the name it mentions</td>
<td>The word or clause it names</td>
</tr>
</tbody></table>
<h2>Practise reading errors, not just fixing them</h2>
<p>The goal isn't to memorise every error. It's to stop being afraid of them. Next time something breaks, before you change a single character, say out loud: <em>what</em> went wrong, <em>where</em>, and what <em>question</em> that raises about your code.</p>
<p>If you're still choosing a first language, start here: <a href="https://craftstackacademy.com/blog/which-programming-language-to-learn-first">Which programming language should you learn first? Python, JavaScript, SQL or Java</a></p>
<p>Want to practise this with real code? At <a href="https://craftstackacademy.com">Craftstack Academy</a>, an AI tutor reads your actual code and your actual error, then gives you a hint about where to look, not the answer. Try one free 20-minute session, with nothing to install: <a href="https://craftstackacademy.com/trial">craftstackacademy.com/trial</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Why Does 0.1 + 0.2 Not Equal 0.3 in Python?]]></title><description><![CDATA[print(0.1 + 0.2) gives 0.30000000000000004. Learn why floating-point numbers do this and how to fix it with round(), math.isclose() and Decimal.]]></description><link>https://craftstack.hashnode.dev/why-does-0-1-0-2-not-equal-0-3-in-python</link><guid isPermaLink="true">https://craftstack.hashnode.dev/why-does-0-1-0-2-not-equal-0-3-in-python</guid><category><![CDATA[Python]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[learn coding]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Craftstack Academy]]></dc:creator><pubDate>Mon, 02 Nov 2026 17:08:22 GMT</pubDate><content:encoded><![CDATA[<p>Open Python and type this:</p>
<pre><code class="language-python">print(0.1 + 0.2)
</code></pre>
<p>You'd expect <code>0.3</code>. Python gives you this:</p>
<pre><code class="language-plaintext">0.30000000000000004
</code></pre>
<p>And it gets stranger:</p>
<pre><code class="language-python">print(0.1 + 0.2 == 0.3)
</code></pre>
<pre><code class="language-plaintext">False
</code></pre>
<p>If you're learning to code, this is the moment you start wondering whether you broke something. You didn't. Python is doing exactly what it was designed to do, and so are JavaScript, Java, C# and almost every other language. Try <code>0.1 + 0.2</code> in your browser's console and you'll get the same <code>0.30000000000000004</code>.</p>
<p>Let's look at why, and what to do about it.</p>
<h2>Computers store numbers in binary</h2>
<p>You count in base 10: every digit is a number of ones, tens, hundreds, and after the decimal point, tenths, hundredths and so on.</p>
<p>Computers count in base 2 (binary). After the "binary point" they only have halves, quarters, eighths, sixteenths…</p>
<p>Some numbers fit perfectly into that system:</p>
<ul>
<li><code>0.5</code> is one half → exact</li>
<li><code>0.25</code> is one quarter → exact</li>
<li><code>0.75</code> is a half plus a quarter → exact</li>
</ul>
<p>But <code>0.1</code> (one tenth) can't be built from halves, quarters and eighths. In binary it's an endless repeating pattern:</p>
<pre><code class="language-plaintext">0.0001100110011001100110011...
</code></pre>
<h2>The same problem you already know: 1/3</h2>
<p>You've seen this in base 10. Try writing one third as a decimal:</p>
<pre><code class="language-plaintext">0.3333333333...
</code></pre>
<p>The threes never stop. At some point you have to cut it off, and the number you wrote down is <em>almost</em> one third, but not exactly.</p>
<p>The computer has the same problem with <code>0.1</code>, just in binary. It has a fixed amount of space for each number (64 bits), so it stores the closest value it can fit. You can see the number Python actually stored:</p>
<pre><code class="language-python">from decimal import Decimal
print(Decimal(0.1))
</code></pre>
<pre><code class="language-plaintext">0.1000000000000000055511151231257827021181583404541015625
</code></pre>
<p>So <code>0.1</code> is really a tiny bit more than 0.1. The same goes for <code>0.2</code>. Add two slightly-off numbers and the tiny errors add up. That's where the extra <code>...04</code> comes from.</p>
<p>It's not only <code>0.1 + 0.2</code>:</p>
<pre><code class="language-python">print(0.1 + 0.7)
</code></pre>
<pre><code class="language-plaintext">0.7999999999999999
</code></pre>
<h2>Why <code>print(0.1)</code> still shows 0.1</h2>
<p>If <code>0.1</code> is stored as <code>0.1000000000000000055...</code>, why does <code>print(0.1)</code> show <code>0.1</code>?</p>
<p>Python is being helpful. When it prints a float, it shows the <em>shortest</em> number that maps back to the same stored value. For <code>0.1</code>, that's simply <code>0.1</code>. But after the addition, the result lands on a slightly different stored value, and the shortest way to write that one is <code>0.30000000000000004</code>.</p>
<h2>How to fix it</h2>
<h3>1. Round when you display a result</h3>
<p>If you only need to <em>show</em> the number, round it:</p>
<pre><code class="language-python">total = 0.1 + 0.2
print(round(total, 2))
print(f"{total:.2f}")
</code></pre>
<pre><code class="language-plaintext">0.3
0.30
</code></pre>
<h3>2. Never compare floats with <code>==</code></h3>
<p>This is the real lesson. Instead of asking "are these exactly equal?", ask "are these close enough?":</p>
<pre><code class="language-python">import math

print(math.isclose(0.1 + 0.2, 0.3))
</code></pre>
<pre><code class="language-plaintext">True
</code></pre>
<p><code>math.isclose()</code> lets a tiny difference through, which is exactly what you want when working with decimals.</p>
<h3>3. Use <code>Decimal</code> when every cent matters</h3>
<p>For money and other places where you need exact decimal math, use the <code>decimal</code> module. Pass the numbers in as <strong>strings</strong>:</p>
<pre><code class="language-python">from decimal import Decimal

print(Decimal("0.1") + Decimal("0.2"))
</code></pre>
<pre><code class="language-plaintext">0.3
</code></pre>
<p>Strings matter here. <code>Decimal(0.1)</code> would copy the already-imprecise float, and you'd be back to <code>0.1000000000000000055...</code>.</p>
<h2>One more surprise: round() isn't magic either</h2>
<p>Now that you know the trick, this one makes sense:</p>
<pre><code class="language-python">print(round(2.675, 2))
</code></pre>
<pre><code class="language-plaintext">2.67
</code></pre>
<p>You'd expect <code>2.68</code>. But <code>2.675</code> is stored as something like <code>2.67499999...</code>, so it rounds down. Same cause, different symptom.</p>
<h2>Quick summary</h2>
<table>
<thead>
<tr>
<th>Situation</th>
<th>What to do</th>
</tr>
</thead>
<tbody><tr>
<td>Showing a decimal to a user</td>
<td><code>round(x, 2)</code> or <code>f"{x:.2f}"</code></td>
</tr>
<tr>
<td>Checking if two decimals are equal</td>
<td><code>math.isclose(a, b)</code>, never <code>==</code></td>
</tr>
<tr>
<td>Money or exact decimal math</td>
<td><code>Decimal("0.1")</code> with strings</td>
</tr>
</tbody></table>
<h2>Try it yourself</h2>
<p>Reading this is one thing. The rule really sticks after you hit the bug yourself. Open Python and try:</p>
<ol>
<li><code>print(0.1 + 0.2 == 0.3)</code>. Predict the answer first.</li>
<li>Find another pair of decimals that doesn't add up cleanly.</li>
<li>Fix the comparison with <code>math.isclose()</code>.</li>
</ol>
<p>Next time Python shows you an error instead of a strange number, here's how to read it: <a href="https://craftstack.hashnode.dev/how-to-read-an-error-message-a-3-step-method-for-python-java-javascript-and-sql">How to Read an Error Message: A 3-Step Method for Python, Java, JavaScript and SQL</a></p>
<p>If you'd like to practise with someone pointing you in the right direction, <a href="https://craftstackacademy.com">Craftstack Academy</a> has an AI coding tutor that reacts to the code you actually write. When you get stuck, it gives you a hint, not the answer, so you still solve it yourself. You can try one free 20-minute session, with nothing to install: <a href="https://craftstackacademy.com/trial">craftstackacademy.com/trial</a>.</p>
]]></content:encoded></item></channel></rss>