Go / Gin

Go "Cannot Use X as Type Y in Assignment" Interface Mismatch

This compile-time error means a value doesn't actually satisfy the interface (or type) you're trying to assign it to — Go's static type checking catches this before the program ever runs, and the fix requires understanding exactly which specific requirement of the target type isn't being met.

The Problem

Code that looks like it should compile fails with:

cannot use myStruct (variable of type MyStruct) as type MyInterface in assignment:
    MyStruct does not implement MyInterface (method DoSomething has pointer receiver)

Or a similar variant without the parenthetical detail, depending on the exact nature of the mismatch:

cannot use result (variable of type int) as type string in assignment

Why It Happens

This error covers a few genuinely distinct scenarios, each requiring a different fix:

  • A straightforward type mismatch — trying to assign an int where a string is expected, or similar, usually from a typo or a misunderstanding of what a function actually returns
  • An interface satisfaction mismatch specifically involving pointer versus value receivers — a method defined with a pointer receiver (func (m *MyStruct) DoSomething()) means only *MyStruct satisfies an interface requiring that method, not a plain MyStruct value, even though this distinction is easy to overlook when reading code casually
  • An interface missing one or more required methods entirely — the concrete type simply hasn't implemented every method the interface declares, so Go correctly refuses to treat it as satisfying that interface
  • A method signature that looks similar but doesn't exactly match what the interface requires (different parameter types, different return types, or a different number of return values), which Go treats as a completely different method for the purposes of interface satisfaction, not a compatible near-match

The Fix

For the pointer-versus-value receiver case specifically (a very common source of this exact error), understand the underlying rule: if any method on a type uses a pointer receiver, only a pointer to that type satisfies interfaces requiring that method — the value type alone does not, even if you never intended to make a distinction:

type MyStruct struct{}

func (m *MyStruct) DoSomething() {} // pointer receiver

type MyInterface interface {
    DoSomething()
}

var s MyStruct
var i MyInterface = s // ERROR: MyStruct doesn't satisfy MyInterface (pointer receiver)

var i MyInterface = &s // Correct: *MyStruct does satisfy it

The fix is either using a pointer when assigning to the interface (as shown above), or, if consistency of value semantics matters for your specific design, changing the method to use a value receiver instead, if that's appropriate for what the method actually does:

func (m MyStruct) DoSomething() {} // value receiver - now MyStruct itself satisfies the interface

For a missing method, the compiler error itself, especially with Go's more detailed error messages in recent versions, usually names the exact missing method directly — implement it on the concrete type to satisfy the interface:

type MyInterface interface {
    DoSomething()
    DoSomethingElse()
}

type MyStruct struct{}
func (m *MyStruct) DoSomething() {}
// DoSomethingElse() is missing - add it:
func (m *MyStruct) DoSomethingElse() {}

For a signature mismatch (a method that exists but doesn't exactly match what's required), compare the interface's declared method signature character-by-character against your implementation, paying particular attention to parameter types and the exact number and types of return values:

// Interface requires:
type Reader interface {
    Read(p []byte) (n int, err error)
}

// This does NOT satisfy it - wrong return type
func (m MyStruct) Read(p []byte) (int, string) { return 0, "" }

// This does satisfy it - matches exactly
func (m MyStruct) Read(p []byte) (int, error) { return 0, nil }

For a genuine type mismatch unrelated to interfaces (assigning an int where a string is expected, for example), trace back to where the mismatched value actually comes from — often a function's return type was misremembered, or a variable was reused for a different purpose than its original type suggests, and the fix is either converting the type explicitly where that's a valid, intentional operation, or correcting the actual logic error causing the wrong type to appear in that position in the first place.

Still Not Working?

If the error involves a complex, deeply nested interface hierarchy and it's hard to determine exactly which specific method is causing the mismatch, use Go's compiler with verbose output, or add an explicit, temporary interface assertion at a more granular point in the code to isolate exactly where the mismatch originates, rather than trying to reason through a complex chain of embedded interfaces and structs purely by reading the code:

var _ MyInterface = (*MyStruct)(nil) // compile-time-only check, isolates interface satisfaction issues

This line, placed anywhere at package level, forces the compiler to check interface satisfaction immediately and in isolation, producing a clear error at that exact line if *MyStruct doesn't satisfy MyInterface, without needing to trace the error back through a larger, more complex assignment elsewhere in the code.