This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Advert's profile picture

Codex Of Error Slaying -2

Started by Advert, 18 February 2012 - 11:11 PM
Advert #1
Posted 19 February 2012 - 12:11 AM
Work-In-Progress; Read below for details. Post any suggestions you may have.
Being updated for 1.3; Some information is incorrect for 1.21, e.g getting line #s all the time


Preface


Hello, and welcome to the Codex of Error Slaying.
In this tutorial, I will be detailing various species of errors, and how to slay them.
If your particular species of error is not here, please reply, post your error, and your entire code (if you do not want to share it, you can PM it to me). Please don't post "just the segment I think the error is in", as I can't run it :)/>/> )

If you are unfamiliar with lua, please have a look at Programming In Lua


[anchor="Index"]Index
[anchor="HP"]Helpful Programs [acronym="Return to Index"]^[/acronym]
  • Casper's debugger May not work for 1.3
  • This will allow you to get a stack trace + the line where your error happened, if you did not get it. You will always get a line # of the error in 1.3; No stack trace, however.
[anchor="RE"]Runtime Errors [acronym="Return to Index"]^[/acronym]




[anchor="AtCN"]Attempt to Call Nil [acronym="Return to Index"]^[/acronym]


What this error means: You are trying to call a variable that is nil:

undefinedFunction() -- This will error.
myFunctions = {}
myFunctions.undefinedFunction() -- This will also error.

In most cases, this is because of a spelling mistake, and/or incorrect capitalization:

print(toString(20)) -- This will error; All lua standard libraries use all-lowercase functions
print(tostring(20)) -- This will work.

term.setcursorpos(5, 10) -- This will error; Computercraft uses camelCase:
term.setCursorPos(5, 10) -- This will work.

"But I've made the function! I know it exists!”
You've probably defined your function after you try to use it!
Here's an example:

sayHello("World")

function sayHello(str)
print("Hello, " .. str)
end

To fix it, simply move your function up (since values are not data, you can do this, even if you call the function in another function; see Chapter 1 for more details)

function sayHello(str)
print("Hello, " .. str)
end

sayHello(“World”)


[anchor="AtIN"]Attempt to index ? (a nil value) [acronym="Return to Index"]^[/acronym]


What this error means: You are trying to get something from nil:


myTable = nil
myTable[20] -- Will error; myTable is nil!

This is very common, especially if you have another function passing a table to one using it:


function getImportantValue(tTable)
return tTable.importantValue
end
local iHaveAnImportantValue = {importantValue = 20}
getImportantValue(iHaveAnlmportantValue) -- This calls getImportantValue without the table,
							   -- getImportantValue is not expecting this!

This is not an "easy" error to track down, especially without an error number.

The best we can do is locate where something is going wrong:
Add checks to your functions, error (with useful info!) if wrong arguments are passed.
Check that things you expect to be tables actually are tables.

This will not "fix" the error, but it will help you locate it. (which ends up being either a typo, wrong argument, forgotten argument, or you expected something to be a table, but it wasn’t (e.g using io.open, but the file can’t open), or a myriad of other problems.)



[anchor="GBFNNSTEBFNNST"]Bad Argument: [Boolean/Function/Nil/Number/String/Table
] Expected, Got [Boolean/Function/Nil/Number/String/Table
]
[acronym="Return to Index"]^[/acronym]


What does this mean?
One of the functions you're calling is erroring, because it recieved the wrong types of arguments!

Example:

function getRoman()
return {i = 1, v = 5, x = 10, l = 50, c = 100, d = 500, m = 1000}
end

print(string.sub(getRoman(), 2, 8)

You'll get a line number, however.

If you go to that line, you can print the types and values of all the varaibles:

function getRoman()
return {i = 1, v = 5, x = 10, l = 50, c = 100, d = 500, m = 1000}
end

-- Line that errors:
print(string.sub(getRoman(), 2, 8)


--Without seeing what myFunction is returning, this can be confusing; so let's print it:
local gRResult = getRoman()
print("gRResult: ", gRResult, " type: ", type(gRResult))

print(string.sub(gRResult, 2, 8)) -- This will still error, but we can see what went wrong now!

Once we determine that we're getting the wrong arguments, we can fix that:

function getRomanNumerals() -- Change the name of our old function.
return {i = 1, v = 5, x = 10, l = 50, c = 100, d = 500, m = 1000}
end
function getRomanAlphabet() -- Take the same precaution with what we intended to do.
return "ABCDEFGHIKLMNOPQRSTVXYZ"
end
print(string.sub(getRomanAlphabet(), 2, 8) -- Use the correct function

Of course, it may not be this simple; so you may have to check variables as they are being passed to your functions, as well.

As a rule of thumb: math.* expects a number as the first argument, string.* expects a string as the first argument, etc.

[anchor="TLWY"]Too Long Without Yielding [acronym="Return to Index"]^[/acronym]


Note: Not really sure how to explain this error;
This means that your computer isn't allowing ComputerCraft to run other computers, and update it's display, etc:


while true do
...
end
This code will cause this error, since there are no points in it that ComputerCraft can pause it, and execute other code.

There are a few ways of fixing this:
The easiest one is:


while true do
sleep(0)
...
end
Adding the sleep call will allow computercraft to do other stuff, then resume your function from where the sleep call is.

Another method is using os.pullEvent in a loop; but I'm not going to explain how to do that here.


[anchor="AIOOB"]vm error: java.lang.ArrayIndexOutOfBoundsException: <number> [acronym="Return to Index"]^[/acronym]


This happens for a few reasons; the ones I've encountered so far are:

1) The stack overflows (<number> will be 256)


function asd()
asd()
end

asd()
This will cause the error; since you will be going deeper into the stack with every call of asd.

You can also do this by using multiple functions:

function a()
b()
end
function b()
c()
end
function c()
a()
end

a()

Possible solutions are:

Tail calls:

You can read more about this here: Programming in Lua c. 6.3


function asd()
return asd()
end
Lua uses tail calls; what this means is that, if you call a function right after the return statement, the stack level will be re-used.

Examples of tail calls:

return asd()
Invalid examples:

return 1, asd() -- Adding return values

local a, b = asd()
return a, b -- Not a tail call; function is called before returning

asd() -- Reducing return values to 0

Looping:
You can use a loop instead of using a function, while storing the data.

(No example yet because lazy + forum editing sux)

2) You're using string.gsub/other string.* function that uses patterns, and your [] are mismatching:


string.gsub("a]b]c]d]", "]", "!")

Possible solutions:

If you just want to match the [ or ] character, use %[ and %].
The % sign escapes non-alphanumeric characters in patterns.

If you're using [] to match a group of characters, you'll need to find out where you're missing them.

[anchor="SE"]Syntax Errors [acronym="Return to Index"]^[/acronym]



These errors are produced when the lexer finds an error, e.g:

if a = b then ... -- you missed a = or a ~; 'then' expected
end

while true do
...
end
end -- An additional end '<eof>' expected

if true then
...
-- Missing an end; 'end' expected

If your error ends with "expected", then this is most likely a syntax error.

[anchor="MP"]Multiple Points [acronym="Return to Index"]^[/acronym]


This error is fairly easy to find, once you figure out what the error means:
You have multiple points (.) in a number!

What will cause this error?

version = 1.0.0 -- This will error! You can't have multiple points in a number!

How would we fix this?
Since you most likely would like to keep the minor version (1.0.0),
you can simply turn it into a string (which is probably what you meant to have it as):

version = "1.0.0" -- Fixed!
version = 1.0 -- If you want to keep it a a number, you’ll have to drop one of the .s
version = 1 -- You can also split it into multiple vars
version_major = 0
version_minor = 0
FuzzyPurp #2
Posted 19 February 2012 - 02:37 AM
Great start! this will sure help alot of people.
Paf #3
Posted 20 February 2012 - 10:01 PM
You've made a small mistake in both of your "Attempting to call nil" example snippets.



function myFunction(str)
print(“Hello, “ .. str)
end

sayHello(“World”)

should really be

function sayHello(str)
print(“Hello, “ .. str)
end
sayHello(“World”)

You should also talk about identifying arguments which needs a string. I was confused with the redstone API at first when I didn't know the side was expected to be a string.

;)/>/>
Advert #4
Posted 20 February 2012 - 10:24 PM
You've made a small mistake in both of your "Attempting to call nil" example snippets.



function myFunction(str)
print(“Hello, “ .. str)
end

sayHello(“World”)

should really be

function sayHello(str)
print(“Hello, “ .. str)
end
sayHello(“World”)

You should also talk about identifying arguments which needs a string. I was confused with the redstone API at first when I didn't know the side was expected to be a string.

;)/>/>

Fixed, thanks :)/>/>
Casper7526 #5
Posted 21 February 2012 - 01:38 AM
might as well remove my debugger as I'm going to out-date it, because 1.3 does everything my debugger does except stack trace ;(
Advert #6
Posted 21 February 2012 - 02:08 AM
might as well remove my debugger as I'm going to out-date it, because 1.3 does everything my debugger does except stack trace ;(
I'll do that when 1.3 is released.
kamnxt #7
Posted 24 March 2012 - 07:38 PM
undefinedFunction() This will error.
myFucntions = {}
myFunctions.undefinedFunction() This will also error.
Did you mean myFunctions?
You wrote myFucntions….
Advert #8
Posted 24 March 2012 - 08:15 PM
undefinedFunction() This will error.
myFucntions = {}
myFunctions.undefinedFunction() This will also error.
Did you mean myFunctions?
You wrote myFucntions….

Fixed, thanks.
Mads #9
Posted 03 April 2012 - 04:22 PM
Can I ask a question?
How do you create anchors in the text? Like when we click a link in the Index, it takes us to a point in the text :)/>/>
Thanks
-mad1231999
Advert #10
Posted 03 April 2012 - 04:56 PM
I used anchor="name", then url="path/to/page#name.
iStone #11
Posted 22 April 2012 - 04:07 PM
I got a problem with the error messages, it only shows what i presume is the error id?

When i get an error it only print out 14, 16 and so on.
Borka223 #12
Posted 23 April 2012 - 04:26 PM
Hello world! I could use some help here, so every reply is appreciated!
I am writing a turtle program, but it shows
bios:206: [string "mine"]:9: 'do' expected 
the code looks like this:

x = 0
y = 0
a = 0
b = turtle.compare
turtle.dig()
turtle.forward()
x = x+1
while turtle.getitemcount<64 do
while turtle.compare() = d do
  turtle.dig()
  turtle.forward()
  x = x+1
end
end
:)/>/>
Advert #13
Posted 23 April 2012 - 05:02 PM
Borka: I'd appreciate it if you'd post that in the correct forum.

iStone: There are no error IDs. Make a thread in Ask A Pro, including your code; It's impossible to help you with the little amount of information you supplied.
MathManiac #14
Posted 19 May 2012 - 12:22 AM
Awesome! meh, I use this as a reference. *clicks green button at lower-left corner of thread*

Also, you should ad a TODO at the bottom of the thread.
PixelToast #15
Posted 30 May 2012 - 12:52 AM
Borka: I'd appreciate it if you'd post that in the correct forum.

iStone: There are no error IDs. Make a thread in Ask A Pro, including your code; It's impossible to help you with the little amount of information you supplied.
if you look at how to fix it you will notice that he did "=" instead of "==" this could be put in the tutorial as when you get a do expected when you already have do then it is most likely a formatting problem with the expression used, easy way to tell people is to add "or do expected" next to syntax errors
ViTALiTY #16
Posted 10 August 2012 - 10:51 PM
Can anyone take a look at this code here and try to tell me whats wrong?

http://pastebin.com/j3sMN7cB

This is the error i get :

sensors:33: attempt to concatenate nil and string
Cranium #17
Posted 10 August 2012 - 10:57 PM
Can anyone take a look at this code here and try to tell me whats wrong?

http://pastebin.com/j3sMN7cB

This is the error i get :

sensors:33: attempt to concatenate nil and string
Try posting in the Ask a Pro section. I know I tried to help you, but this thread is pretty dead. However, there are a lot of people willing to help there.
Skullblade #18
Posted 28 October 2012 - 08:17 PM
DEAD FORUM
PixelToast #19
Posted 28 October 2012 - 11:53 PM
DEAD FORUM
not really, its still useful for debugging without posting it to ask a pro whenever you get an error
Skullblade #20
Posted 30 October 2012 - 09:17 PM
Yeah its still helpful but no one is talking on it
ekzane #21
Posted 14 December 2012 - 08:40 AM
Too Long Without Yielding


Note: Not really sure how to explain this error;
[…]

Thats quiet easy:
Every program on every CC computer runs one after the another. This is going so fast, that it looks like its done parallel.
Now imagine your program is now in a loop "without yielding", which means that your program is the only one running in Minecraft and doesn't let other programs run.
Gladly your program will break with the error above and so let other programs do their work.

How do I make it "yield", you may ask. Several ways are

coroutine.yield()

os.pullEventRaw()

os.pullEvent()
and

sleep()

Hint: Internally sleep() calls os.pullEvent(), which calls os.pullEventRaw(), which calls coroutine.yield() and thus "yielding" your program.

sleep(0) is a good choice for beginners though :)/>
RunasSudo-AWOLindefinitely #22
Posted 27 December 2012 - 02:32 AM
My explanation of stack overflow:
If function a() calls function b(), lua records this "changeover" of functions in the system stack.
In this case, the stack would look like

a()
- b()
If function b() then called function c(), which called function d(), the stack would look like

a()
- b()
  - c()
    - d()
If function a() calls itself, then the stack looks like

a()
- a()
  - a()
    - a()
      - a()
		  ...
The stack only goes to function #255, so when a() calls itself the 256th time, the stack "overflows" and throws the error. (It's like trying to put 256 mL of water into a container which only holds 255 mL)
krodus #23
Posted 08 February 2013 - 05:27 PM
Thank you for this awesome tut.
KingofGamesYami #24
Posted 12 February 2013 - 12:28 PM
[Your post does not belong here, it belongs in Ask a Pro. There is a sticky topic there for new members to ask questions. I moved your last post in this topic to the Ask a Pro section for you. You can find it here: http://www.computercraft.info/forums2/index.php?/topic/10406-expected-error -L]
hedgehog1029 #25
Posted 26 May 2013 - 07:40 AM
The best way to explain Too Long Without Yielding is to say: Your loop has no delay, so it will try to run too quickly possibly crashing the game. I learnt this from playing ROBLOX.
theoriginalbit #26
Posted 26 May 2013 - 07:51 AM
The best way to explain Too Long Without Yielding is to say: Your loop has no delay, so it will try to run too quickly possibly crashing the game. I learnt this from playing ROBLOX.
The problem is there is no such thing as a program running too quick to crash itself.

This would be the easiest way to explain it:
``The error occurs when your program runs for approximately 10 seconds without letting any other computer or turtle run (failure to yield); this is not allowed. To have the computer yield you call one of 4 functions: sleep, os.pullEvent, os.pullEventRaw or coroutine.yield;``

Another way to explain it:
``In ComputerCraft only one computer is running at a time, it may seem like they are all running at once, but they aren't. Only a single computer is allowed to run at any given time, and it must give up its run privilege within a respectable amount of time (yield) to allow other computers to execute their code, if it does not the program will be halted via an error to allow other computers to resume normal operation. To have your program yield you can call one of 4 functions: sleep, os.pullEvent, os.pullEventRaw or coroutine.yield;``
Dlcruz129 #27
Posted 28 May 2013 - 12:09 AM
The best way to explain Too Long Without Yielding is to say: Your loop has no delay, so it will try to run too quickly possibly crashing the game. I learnt this from playing ROBLOX.
The problem is there is no such thing as a program running too quick to crash itself.

This would be the easiest way to explain it:
``The error occurs when your program runs for approximately 10 seconds without letting any other computer or turtle run (failure to yield); this is not allowed. To have the computer yield you call one of 4 functions: sleep, os.pullEvent, os.pullEventRaw or coroutine.yield;``

Another way to explain it:
``In ComputerCraft only one computer is running at a time, it may seem like they are all running at once, but they aren't. Only a single computer is allowed to run at any given time, and it must give up its run privilege within a respectable amount of time (yield) to allow other computers to execute their code, if it does not the program will be halted via an error to allow other computers to resume normal operation. To have your program yield you can call one of 4 functions: sleep, os.pullEvent, os.pullEventRaw or coroutine.yield;``

And to users who do not know, os.pullEvent is the same as coroutine.yield.
hedgehog1029 #28
Posted 04 June 2013 - 12:12 PM
The best way to explain Too Long Without Yielding is to say: Your loop has no delay, so it will try to run too quickly possibly crashing the game. I learnt this from playing ROBLOX.
The problem is there is no such thing as a program running too quick to crash itself.

This would be the easiest way to explain it:
``The error occurs when your program runs for approximately 10 seconds without letting any other computer or turtle run (failure to yield); this is not allowed. To have the computer yield you call one of 4 functions: sleep, os.pullEvent, os.pullEventRaw or coroutine.yield;``

Another way to explain it:
``In ComputerCraft only one computer is running at a time, it may seem like they are all running at once, but they aren't. Only a single computer is allowed to run at any given time, and it must give up its run privilege within a respectable amount of time (yield) to allow other computers to execute their code, if it does not the program will be halted via an error to allow other computers to resume normal operation. To have your program yield you can call one of 4 functions: sleep, os.pullEvent, os.pullEventRaw or coroutine.yield;``
On ROBLOX Lua is executed via scripts which run and stop when it reaches a certain function, like:

function onTouchBlock()
(code for touching a block, can't be bothered to write it out :P/>)
end
But thanks for the new knowledge, now I know :P/>
Thib0704 #29
Posted 22 July 2013 - 02:18 PM
Thank's for this info !
NOTUSEDPLEASEDELETE #30
Posted 23 August 2013 - 09:14 PM
Another error:
'unfinished string'. It simply means you forgot to add a string bracket (',") for a string.
e.g.
Incorrect:

print("Hello World)
Correct:

print("Hello World")
Zudo #31
Posted 24 August 2013 - 03:22 AM
Another error:
'unfinished string'. It simply means you forgot to add a string bracket (',") for a string.
e.g.
Incorrect:

print("Hello World)
Correct:

redstone.setOutput("bottom", true)

Why did you use a different example?
NOTUSEDPLEASEDELETE #32
Posted 07 September 2013 - 04:05 AM
Another error:
'unfinished string'. It simply means you forgot to add a string bracket (',") for a string.
e.g.
Incorrect:

print("Hello World)
Correct:

redstone.setOutput("bottom", true)

Why did you use a different example?

Fixed.