The := operator in Go is failing because you’re trying to use it with something that isn’t a new variable declaration on the left-hand side. This operator is specifically designed for short variable declarations, meaning the identifier on the left must be new in the current scope.

Here’s what’s actually breaking:

The Go compiler enforces that := can only be used when declaring at least one variable that hasn’t been seen before in the current block of code. If all variables on the left are already declared, Go doesn’t know what to do; it can’t assign a new value to an existing variable using := (that’s what = is for) and it can’t declare a new variable if there are none.

Here are the common culprits and how to fix them:

1. Re-declaring an existing variable:

  • Diagnosis: You’ve already declared a variable with the same name in the current scope and are now trying to use := again.
    package main
    
    func main() {
        x := 10 // First declaration
        x := 20 // Error: no new variables on left side of :=
        _ = x
    }
    
  • Fix: Use the = assignment operator instead of := for existing variables.
    package main
    
    func main() {
        x := 10 // First declaration
        x = 20  // Correct: assign to existing variable
        _ = x
    }
    
  • Why it works: = is the standard assignment operator, used to change the value of an already declared variable. := is for short variable declaration.

2. Declaring a variable outside its intended scope:

  • Diagnosis: You’re trying to declare a variable using := in a scope where it has already been declared in an enclosing scope, but you’re not using it correctly.
    package main
    
    var globalVar int // Declared outside main
    
    func main() {
        // globalVar = 10 // This would be a valid assignment
        // globalVar := 20 // Error: no new variables on left side of :=
    }
    
  • Fix: If you intend to modify a global or outer-scoped variable, use the = assignment operator. If you intend to declare a new variable that shadows the outer one within main, then := is correct if it’s truly a new declaration within main’s scope. The error arises when you try to := something that already exists and is not being shadowed.
    package main
    
    var globalVar int
    
    func main() {
        globalVar = 20 // Correct: assign to the global variable
    }
    
    Or, if you want a new variable in main:
    package main
    
    var globalVar int
    
    func main() {
        localVar := 20 // Correct: declares a new variable 'localVar' within main
        _ = localVar
    }
    
  • Why it works: Go’s scope rules mean you can’t redeclare a variable with := if it exists in an outer scope and you’re not intending to shadow it. If you are intending to shadow, the syntax varName := ... is correct, but the error means the compiler thinks you’re trying to redeclare something that isn’t truly new in that specific block.

3. Using := inside a for loop’s initialization statement:

  • Diagnosis: Trying to declare a new variable with := when the variable already exists within the loop’s scope.
    package main
    
    func main() {
        i := 0
        for ; i < 5; i++ { // Error: no new variables on left side of :=
            // ...
        }
    }
    
    Or more commonly:
    package main
    
    func main() {
        for i := 0; i < 5; i++ { // i is declared here
            // ...
        }
        // i = 10 // This is fine
        // i := 10 // Error: no new variables on left side of :=
    }
    
  • Fix: If i is already declared and you just want to assign to it, use =. If you are inside a new block and want to declare a new i that shadows, that’s fine. The error occurs when you try to := an existing variable.
    package main
    
    func main() {
        i := 0
        for ; i < 5; i++ { // Correct: i is already declared, so we don't use :=
            // ...
        }
    }
    
    Or if you want to declare a new i within the loop’s init, that’s the standard way:
    package main
    
    func main() {
        for i := 0; i < 5; i++ { // Correct: declares 'i' for the first time in this loop's scope
            // ...
        }
    }
    
  • Why it works: The for loop’s initialization part for init; condition; post is a specific scope. If i was declared before the loop and you’re trying to use := in the init part, it’s a redeclaration error. If i is declared in the init part, it’s new to that loop’s scope. The error usually happens when you try to := a variable that’s already in scope outside the loop’s init statement.

4. Incorrectly using := with range:

  • Diagnosis: Trying to assign to a variable that’s already been declared when iterating over a range.
    package main
    
    func main() {
        myMap := map[string]int{"a": 1}
        for k, v := range myMap { // k and v are declared here
            // ...
        }
        // k := "b" // Error: no new variables on left side of :=
    }
    
  • Fix: If you want to assign to k after the loop, use =. If you want to declare a new variable k that shadows the one from the loop, := is correct if it’s in a new scope. The error means k is still in scope from the range and you’re trying to := it again.
    package main
    
    func main() {
        myMap := map[string]int{"a": 1}
        for k, v := range myMap {
            // ...
        }
        k = "b" // Correct: assign to the existing k
        _ = k
    }
    
  • Why it works: Similar to the for loop, variables declared by range are scoped to the loop. If you try to := them after the loop within the same scope, it’s a redeclaration error.

5. Using := in a switch statement’s case or default:

  • Diagnosis: Attempting to declare a new variable with := within a case or default block when a variable with that name already exists in the surrounding switch scope.
    package main
    
    func main() {
        switch {
        case true:
            x := 10 // Declares x in the switch's scope
            _ = x
        case false:
            // x := 20 // Error: no new variables on left side of :=
            _ = 20
        }
    }
    
  • Fix: If you want to assign to an existing variable x within a case, use =. If you want a truly new variable that shadows, make sure it’s in a distinct block (e.g., by adding curly braces {}) or that x wasn’t declared in the switch scope at all.
    package main
    
    func main() {
        switch {
        case true:
            x := 10
            _ = x
        case false:
            x = 20 // Correct: assign to existing x
            _ = x
        }
    }
    
  • Why it works: Variables declared with := in the switch statement’s expression or in a case are scoped to the switch. Trying to := again within another case or the default when it’s already in scope is a redeclaration.

6. Forgetting to declare a variable before assigning:

  • Diagnosis: This is the inverse of the above: you’re trying to assign a value to a variable that has never been declared in the current scope or any enclosing scope.
    package main
    
    func main() {
        // y := 5 // Missing declaration
        y = 10 // Error: undefined: y
    }
    
  • Fix: Declare the variable first using var or :=.
    package main
    
    func main() {
        y := 10 // Correct: declare and assign
        _ = y
    }
    
    Or:
    package main
    
    func main() {
        var y int
        y = 10 // Correct: declare first, then assign
        _ = y
    }
    
  • Why it works: You can’t assign a value to a variable that the compiler doesn’t know exists. := handles both declaration and assignment in one step for new variables.

The next error you’ll likely encounter after fixing these is a "declared and not used" error if you haven’t assigned the variable to anything or used it in a meaningful way.

Want structured learning?

Take the full Golang course →