- Forgetting the . Prefix When Calling Contracts The mistake:
lisp
(contract-call? counter count-up)
;; Error: UnknownContract
Why it happens:
In Clarity, every contract is identified by its deployer address and contract name. When you're working in the Clarinet console, the . before a contract name (e.g., .counter) is shorthand for the fully qualified identifier — it tells Clarity to look for the contract deployed by the current transaction sender.
Without the . prefix, Clarity has no idea which contract you're referring to.
The fix:
lisp
(contract-call? .counter count-up)
;; (ok true) ✅
Always use .contract-name when calling contracts in the Clarinet console.
- Using Wrong Integer Types (1 vs u1) The mistake:
lisp
(define-data-var my-count uint 0)
;; Error: TypeMismatch
Why it happens:
Clarity has two distinct integer types:
int
— signed integers (can be negative): 1, -5, 100
uint — unsigned integers (non-negative only): u1, u0, u100
These types are not interchangeable. If a function expects a uint, you must use the u prefix.
The fix:
lisp
(define-data-var my-count uint u0)
;; ✅ Works correctly
Quick rule: If you see uint in a type signature, always prefix your numbers with u.
- Missing Parentheses The mistake:
lisp
define-public count-up
ok map-set counters tx-sender u1
Why it happens:
Clarity uses Lisp-style syntax, where every expression is wrapped in parentheses. Coming from languages like JavaScript or Python, this takes some getting used to.
The fix:
lisp
(define-public (count-up)
(ok (map-set counters tx-sender u1))
)
Tip: Use a code editor with bracket matching (like VS Code with the Clarity extension) to catch mismatched parentheses early.
- Confusing let and define-data-var The mistake:
Using define-data-var when you just need a temporary local variable, or expecting
let
bindings to persist across function calls.
Why it happens:
define-data-var creates persistent on-chain storage that lives as long as the contract exists
let
creates temporary local variables that only exist within that function call
The fix:
lisp
;; Use let for temporary calculations
(define-read-only (get-double-count (who principal))
(let ((count (get-count who)))
(* count u2)
)
)
;; Use define-data-var for state that persists
(define-data-var contract-owner principal tx-sender)
- Not Handling none from Map Lookups The mistake:
lisp
(map-get? counters tx-sender)
;; Returns (some u5) or none — not a raw uint!
Why it happens:
map-get? returns an optional type — either
(some value)
or none. You can't use the result directly as a uint without unwrapping it first.
The fix:
lisp
;; Use default-to for a fallback value
(default-to u0 (map-get? counters tx-sender))
;; Or use unwrap! / unwrap-panic for strict handling
(unwrap! (map-get? counters tx-sender) (err u404))
Wrapping Up
These mistakes are totally normal when starting out with Clarity. The language is intentionally strict — it's designed to catch bugs at compile time rather than letting them slip into production on a blockchain where errors can be costly.
Resources to keep learning:
. Clarity Language Reference
. Clarinet Quickstart
. Stacks Developer Discord
. Clarity Crash Course
. Happy building! 🚀
Top comments (0)