§40   Error messages

Five kinds of error are reported by Inform: a fatal error is a breakdown severe enough to make Inform stop working at once; an error allows Inform to continue for the time being, but will normally cause Inform not to output the story file (because it is suspected of being damaged); and a warning means that Inform suspects you may have made a mistake, but will not take any action itself. The fourth kind is an ICL error, where a mistake has been made in a file of ICL commands for Inform to follow: an error on the command line is called a “command line error” but is just another way to get an ICL error. And the fifth is a compiler error, which appears if Inform's internal cross-checking shows that it is malfunctioning. The text reporting a compiler error asks the user to report it the author of Inform.

Fatal errors

1. Too many errors

Too many errors: giving up

After 100 errors, Inform stops, in case it has been given the wrong source file altogether, such as a program written in a different language.

· · · · ·

2. Input/output problems

Most commonly, Inform has the wrong filename:

Couldn't open source file filename
Couldn't open output file filename

(and so on). More seriously the whole process of file input/output (or “I/O”) may go wrong for some reason to do with the host computer: for instance, if it runs out of disc space. Such errors are rare and look like this:

I/O failure: couldn't read from source file
I/O failure: couldn't backtrack on story file for checksum

and so forth. The explanation might be that two tasks are vying for control of the same file (e.g., two independent Inform compilations trying to write a debugging information file with the same name), or that the file has somehow been left “open” by earlier, aborted compilation. Normally you can only have at most 256 files of source code in a single compilation. If this limit is passed, Inform generates the error

Program contains too many source files: increase #define MAX_SOURCE_FILES

This might happen if file A includes file B which includes file C which includes file A which… and so on. Finally, if a non-existent pathname variable is set in ICL, the error

No such path setting asname

is generated.

· · · · ·

3. Running out of things

If there is not enough memory even to get started, the following appear:

Run out of memory allocating n bytes for something
Run out of memory allocating array of nxm bytes for something

More often memory will run out in the course of compilation, like so:

The memory setting setting (which is value at present) has been exceeded. Try running Inform again with $setting=larger-value on the command line.

(For details of memory settings, see §39 above.) In a really colossal game, it is just conceivable that you might hit

One of the memory blocks has exceeded 640K

which would need Inform to be recompiled to get around (but I do not expect anyone ever to have this trouble, because other limits would be reached first). Much more likely is the error

The story file/module exceeds version n limit (mK) by b bytes

If you're already using version 8, then the story file is full: you might be able to squeeze more game in using the Abbreviate directive, but basically you're near to the maximum game size possible. Otherwise, the error suggests that you might want to change the version from 5 to 8, and the game will be able to grow at least twice as large again. It's also possible to run out not of story file space but of byte-accessible memory:

This program has overflowed the maximum readable-memory size of the Z-machine format. See the memory map below: the start of the area marked "above readable memory" must be brought down to $10000 or less.

Inform then prints out a memory map so that you can see what contributed to the exhaustion: there is detailed advice on this vexatious error in §45. Finally, you can also exhaust the number of classes:

Inform's maximum possible number of classes (whatever amount of memory is allocated) has been reached. If this causes serious inconvenience, please contact the author.

At time of writing, this maximum is 256 and nobody has yet contacted the author.

Errors

In the following, anything in double-quotes is a quotation from your source code; other strings are in single-quotes. The most common error by far takes the form:

Expected ... but found ...

There are 112 such errors, most of them straightforward to sort out, but a few take some practice. One of the trickiest things to diagnose is a loop statement having been misspelt. For example, the lines

pritn "Hello";
While (x == y) print "x is still y^";

produce one error each:

line 1: Error: Expected assignment or statement but found pritn
line 2: Error: Expected ';' but found print

The first is fine. The second is odd: a human immediately sees that While is meant to be a while loop, but Inform is not able to make textual guesses like this. Instead Inform decides that the code intended was

While (x == y); print "x is still y^";

with While assumed to be the name of a function which hasn't been declared yet. Thus, Inform thinks the mistake is that the ; has been missed out.

In that example, Inform repaired the situation and was able to carry on as normal in subsequent lines. But it sometimes happens that a whole cascade of errors is thrown up, in code which the user is fairly sure must be nearly right. What has happened is that one syntax mistake threw Inform off the right track, so that it continued not to know where it was for many lines in a row. Look at the first error message, fix that and then try again.

· · · · ·

1. Reading in the source-code

In that last error message, “number” is used in the linguistic sense, of singular versus plural.

· · · · ·

2. Characters

Characters are given by ISO Latin-1 code number if in this set, and otherwise by Unicode number, and are also printed if this is possible. For instance, if you try to use an accented character as part of an identifier name, you cause an error like so:

Error: Illegal character found in source: (ISO Latin1) $e9, i.e., 'e'
> Object cafe

because identifiers may only use the letters A to Z, in upper and lower case, the digits 0 to 9 and the underscore character _. The same kind of error is produced if you try to use (say) the ^ character outside of quotation marks. The characters legal in unquoted Inform source code are:

new-line› ‹form-feed› ‹space› ‹tab
0123456789
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
()[]{}<>"',.:;?!+-*/%=&|~#@_

· · · · ·

3. Variables and arrays

The limit of 233 global variables is absolute: a program even approaching this limit should probably be making more use of object properties to store its information. “Entries… must be known constants” is a restriction on what byte or string arrays may contain: basically, numbers or characters; defined constants (such as object names) may only be used if they have already been defined. This restriction does not apply to the more normally used word and table arrays.

· · · · ·

4. Routines and function calls

Note that the system function random, when it takes more than one argument, can only take constant arguments, as this enables the possibilities to be stored efficiently within the program. Thus random(random(10), location) will produce an error. To make a random choice between non-constant values, write a switch statement instead.

· · · · ·

5. Expressions and arithmetic

“Operators” include not only addition +, multiplication * and so on, but also higher-level things like --> (“array entry”) and . (“property value”) and :: (“superclass”). An example of an operator where “Evaluating this has no effect” is in the statement

34 * score;

where the multiplication is a waste of time, since nothing is done with the result. “= applied to ‹operator›” means something like

(4 / fish) = 7;

which literally means “set 4/fish to 7” and gives the error “= applied to /”.

“Brackets mandatory to clarify order” means that an expression is unclear as written, and this is often a caution that it would be wrong either way and needs to be reconsidered. For instance:

if (parent(axe) == location == Hall_of_Mists) ...

This looks as if it might mean “if these three values are all equal”, but does not: the result of == is either true or false, so whichever comparison happens first, the other one compares against one of these values.

· · · · ·

6. Miscellaneous errors in statements

For instance, print (bold) X gives the “reserved word in print specification” error because bold is a keyword that has some meaning already (the statement style bold; changes the type face to bold). Anyway, call such a printing routine something else.

· · · · ·

7. Object and class declarations

Note that “common properties” (those provided by the library, or those declared with Property) cannot be made private. All other properties arecalled “individual”. The “number of duplicates” referred to is the number of duplicate instances to make for a new class, and it needs to be a number Inform can determine now, not later on in the source code (or in another module altogether). The limit 10,000 is arbitrary and imposed to help prevent accidents: in practice available memory is very unlikely to permit anything like this many instances.

· · · · ·

8. Grammar

At present verbs are limited to 20 grammar lines each, though this would be easy to increase. (A grammar of this kind of length can probably be written more efficiently using general parsing routines, however.)

· · · · ·

9. Conditional compilation

“Condition can't be determined” only arises for Iftrue and Iffalse, which make numerical or logical tests: for instance,

Iftrue #strings_offset == $4a50;

can't be determined because, although both quantities are constants, the value of #strings_offset will not be known until compilation is finished. On the other hand, for example,

Iftrue #version_number > 5;

can be determined at any time, as the version number was set before compilation.

· · · · ·

10. Miscellaneous errors in directives

· · · · ·

11. Linking and importing

Note that the errors beginning “Link:” are exactly those occurring during the process of linking a module into the current compilation. They mostly arise when the same name is used for one purpose in the current program, and a different one in the module.

· · · · ·

12. Assembly language

· · · · ·

13. Deliberate “errors”

Finally, error messages can also be produced from within the program (deliberately) using Message. It may be that a mysterious message is being caused by an included file written by someone other than yourself.

Warnings

1. Questionable practices

type› ‹name declared but not used

For example, a Global directive was used to create a variable, which was then never used in the program.

'=' used as condition: '==' intended?

Although a line like

if (x = 5) print "My name is Alan Partridge.";

is legal, it's probably a mistake: x = 5 sets x to 5 and results in 5, so the condition is always true. Presumably it was a mistype for x == 5 meaning “test x to see if it's equal to 5”.

Unlike C, Inform uses ':' to divide parts of a 'for' loop specification: replacing ';' with ':'

Programmers used to the C language will now and then habitually type a for loop in the form

for (i=0; i<10; i++) ...

but Inform needs colons, not semicolons: however, as it can see what was intended, it makes the correction automatically and issues only a warning.

Missing ','? Property data seems to contain the property name name

The following, part of an object declaration, is legal but unlikely:

with found_in MarbleHall
     short_name "conch shell", name "conch" "shell",

As written, the found_in property has a list of three values: MarbleHall, short_name and "conch shell". short_name throws up the warning because Inform suspects that a comma was missed out and the programmer intended

with found_in MarbleHall,
     short_name "conch shell", name "conch" "shell",

This is not a declared Attribute: name

Similarly, suppose that a game contains a pen. Then the following give statement is dubious but legal:

give MarbleDoorway pen;

The warning is caused because it's far more likely to be a misprint for

give MarbleDoorway open;

Without bracketing, the minus sign '-' is ambiguous

For example,

Array Doubtful --> 50 10 -20 56;

because Inform is not sure whether this contains three entries (the middle one being 10 − 20 = −10), or four. It guesses four, but suggests brackets to clarify the situation.

Entry in '->' or 'string' array not in range 0 to 255

Byte -> and string arrays can only hold numbers in the range 0 to 255. If a larger entry is supplied, only the remainder mod 256 is stored, and this warning is issued.

This statement can never be reached

There is no way that the statement being compiled can ever be executed when the game is played. Here is an obvious example:

return; print "Goodbye!";

where the print statement can never be reached, because a return must just have happened. Beginners often run into this example:

"You pick up the gauntlet."; score = score + 5; return;

Here the score = score + 5 statement is never reached because the text, given on its own, means “print this, then print a new-line, then return from the current routine”. The intended behaviour needs something like

score = score + 5; "You pick up the gauntlet.";

Verb disagrees with previous verbs: verb

The Extend only directive is used to cleave off a set of synonymous English verbs and make them into a new Inform verb. For instance, ordinarily “take”, “get”, “carry” and “hold” are one single Inform verb, but this directive could split off “carry” and “get” from the other two. The warning would arise if one tried to split off “take” and “drop” together, which come from different original Inform verbs. (It's still conceivably usable, which is why it's a warning, not an error.)

This does not set the final game's statusline

An attempt to choose, e.g., Statusline time within a module, having no effect on the program into which the module will one day be linked. Futile. Finally a ragbag of unlikely and fairly self-explanatory contingencies:

The last of these messages is to allow for different module formats to be introduced in future releases of Inform, but so far there has only ever been module format 1, so nobody has ever produced this error.

· · · · ·

2. Obsolete usages

These all occur if Inform compiles a syntax which was correct under Inform 5 (or earlier) but has now been withdrawn in favour of something better.

▲▲ No Inform library file (or any other file marked System_file) produces warning messages. It may contain many declared but unused routines, or may contain obsolete usages for the sake of backward compatibility.