Skip to content

Troubleshooting

Common errors

Here are some common errors that appear when compiling SmartPy contracts:

  • Error: NameError: name 'sp' is not defined

    Explanation: SmartPy was not imported.

    Resolution: Add import smartpy as sp at the beginning of the Python file.

  • Error: module 'smartpy' has no attribute 'Contract'

    Explanation: The SmartPy code is not inside a SmartPy module.

    Resolution: Put smart contract code in a .spy file and add it to the scenario or inline it into the scenario file as a function decorated with @sp.module.

  • Errors that refer to sp.unknown or sp.int_or_nat

    Explanation: SmartPy was unable to infer the type of a variable, parameter, or storage field. Because contracts must specify the type of their storage and parameters at deployment time, SmartPy must know the type of variables in storage and in entrypoints.

    Resolution: Ensure that SmartPy can infer types by trying these solutions:

    • Ensure that the types of storage fields are clear. For example, if your contract stores a number, you may need to cast it to sp.int or sp.nat to clarify what type the number is. Errors that refer to sp.int_or_nat may mean that SmartPy can't tell if a variable is an integer or a nat.

    • Similarly, ensure that the types of entrypoint parameters are clear by using type hints. Often, SmartPy can infer the type of a parameter by how it is used. For example, if a storage field is an integer and an entrypoint adds a parameter to that integer, the parameter must also be an integer. However, if SmartPy doesn't have a reference point, it may not be able to determine the type of a parameter. For example, if a storage field is a list and it gets initialized with an empty list, SmartPy would not have enough information to determine what type of elements the list contains.

    • Ensure that you are passing the correct parameter type. For example, if an entrypoint takes an integer as a parameter and you pass a nat, SmartPy throws the error entrypoint expects parameter of type sp.unknown, but got sp.nat: mismatch between sp.int and sp.nat.

  • Errors that refer to Expected type sp.record().layout()

    Explanation: Often this error means that an entrypoint expected parameters to be named fields in a record instead of a list.

    Resolution: To pass multiple parameters to an entrypoint, pass them as a record. For example, if the entrypoint is defined as def myEntrypoint(self, param1, param2), call it with the code contract.myEntrypoint(param1 = 4, param2 = 3).

  • Error: Cannot convert expression to bool.

    Explanation: You cannot access information about a contract outside the test simulation. If you try to, SmartPy returns an expression that you can evaluate in the simulation later, not the value that you might expect.

    For example, if a contract stores a number, you can't use it directly from the contract object as you might expect, as in this code:

    smartpy
    b = contract.data.value  # b is an expression, not a primitive value
    assert b > 9  # Exception: Cannot convert expression to bool.

    Resolution: Access contracts and expressions inside the simulation by using functions such as scenario.verify, as in this example:

    smartpy
    scenario.verify(contract.data.value > 9)
  • Error: Missing variant 'x' or New command outside of contract

    Explanation: x is not a method or attribute of the specified object. These errors can appear if you use a method on the wrong object, such as if you call sp.verify instead of scenario.verify.

    Resolution: Make sure that you are accessing the correct object.

  • Error: [module name] is not defined. or name [function name] is not defined

    Explanation: SmartPy couldn't find the module or a function in a module.

    Resolution: If you are using a library inside SmartPy contract code then import the module first, as in this example:

    smartpy
    @sp.module
    def main():
        import smartpy.stdlib.list_utils as lu
    
        class C(sp.Contract):
            def __init__(self):
                self.data = lu.replicate((3, 5))

    If you are using a library inside a test scenario then remember to add it to the scenario first, as in this example:

    python
    @sp.add_test()
    def test():
        scenario = sp.test_scenario("A Test")
        m = scenario.add_module("my/local/files/contracts.spy")
        contract = m.MyContract()
        scenario += contract

    As a convenience, the SmartPy standard library can be accessed in test scenarios with sp.stdlib, as in this example:

    python
    scenario = sp.test_scenario("my_test")
    scenario.verify(sp.stdlib.utils.mutez_to_nat(sp.mutez(1)) == sp.nat(1))