DM4 §40: Error messages

## §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 as` ‹name›

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` ‹n›`x`‹m›`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 (`‹m›`K) 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

- `Unrecognised combination in source:` ‹text›
- `Alphabetic character expected after` ‹text›
- `Name exceeds the maximum length of` ‹number›`characters:` ‹name›
- `Binary number expected after '$$'`
- `Hexadecimal number expected after '$'`
- `Too much text for one pair of quotations '...' to hold`
- `Too much text for one pair of quotations "..." to hold`
- `No text between quotation marks ''`
- `Expected 'p' after '//' to give number of dictionary word` ‹word›

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

· · · · ·

#### 2. Characters

- `Illegal character found in source:` ‹char›
- `No such accented character as` ‹text›
- `'@{' without matching '}'`
- `At most four hexadecimal digits allowed in '@{...}'`
- `'@{...}' may only contain hexadecimal digits`
- `'@..' must have two decimal digits`
- `Character can be printed but not input:` ‹char›
- `Character can be printed but not used as a value:` ‹char›
- `Alphabet string must give exactly 23 [or 26] characters`
- `Character can't be used in alphabets unless entered into Zcharacter table:` ‹char›
- `Character must first be entered into Zcharacter table:` ‹char›
- `Character can only be used if declared in advance as part of 'Zcharacter table':` ‹char›
- `Character duplicated in alphabet:` ‹char›
- `No more room in the Zcharacter table`

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

- `Variable must be defined before use:` ‹name›
- `'=' applied to undeclared variable`
- `Local variable defined twice:` ‹name›
- `All 233 global variables already declared`
- `No array size or initial values given`
- `Array sizes must be known now, not externally defined`
- `An array must have a positive number of entries`
- `A 'string' array can have at most 256 entries`
- `An array must have between 1 and 32767 entries`
- `Entries in byte arrays and strings must be known constants`
- `Missing ';' to end the initial array values before "[" or "]"`

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

- `No 'Main' routine has been defined`
- `It is illegal to nest routines using '#['`
- `A routine can have at most 15 local variables`
- `Argument to system function missing`
- `System function given with too many arguments`
- `Only constants can be used as possible 'random' results`
- `A function may be called with at most 7 arguments`
- `Duplicate definition of label:` ‹name›
- `The following name is reserved by Inform for its own use as a routine name; you can use it as a routine name yourself (to override the standard definition) but cannot use it for anything else:` ‹name›

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

- `Missing operator: inserting '+'`
- `Evaluating this has no effect:` ‹operator›
- `'=' applied to` ‹operator›
- `Brackets mandatory to clarify order of:` ‹operator›
- `Missing operand for` ‹operator›
- `Missing operand after` ‹something›
- `Found '(' without matching ')'`
- `No expression between brackets '(' and ')'`
- `'or' not between values to the right of a condition`
- `'has'/'hasnt' applied to illegal attribute number`
- `Division of constant by zero`
- `Signed arithmetic on compile-time constants overflowed the range -32768 to +32767:` ‹calculation›
- `Label name used as value:` ‹name›
- `System function name used as value:` ‹name›
- `No such constant as` ‹name›
- `The obsolete '#w$word' construct has been removed`

“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

- `'do' without matching 'until'`
- `'default' without matching 'switch'`
- `'else' without matching 'if'`
- `'until' without matching 'do'`
- `'break' can only be used in a loop or 'switch' block`
- `At most 32 values can be given in a single 'switch' case`
- `Multiple 'default' clauses defined in same 'switch'`
- `'default' must be the last 'switch' case`
- `'continue' can only be used in a loop block`
- `A reserved word was used as a print specification:` ‹name›
- `No lines of text given for 'box' display`
- `In Version 3 no status-line drawing routine can be given`
- `The 'style' statement cannot be used for Version 3 games`

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

- `Two textual short names given for only one object`
- `The syntax '->' is only used as an alternative to 'Nearby'`
- `Use of '->' (or 'Nearby') clashes with giving a parent`
- `'->' (or 'Nearby') fails because there is no previous object`
- `'-> -> ...' fails because no previous object is deep enough`
- `Two commas ',' in a row in object/class definition`
- `Object/class definition finishes with ','`
- ‹name›`is a name already in use (with type` ‹type›`) and may not be used as a property name too`
- `Property given twice in the same declaration, because the names '`‹name›`' and '`‹name›`' actually refer to the same property`
- `Property given twice in the same declaration:` ‹name›
- `Property should be declared in 'with', not 'private':` ‹name›
- `Limit (of 32 values) exceeded for property` ‹name›
- `An additive property has inherited so many values that the list has overflowed the maximum 32 entries`
- `Duplicate-number not known at compile time`
- `The number of duplicates must be 1 to 10000`

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

- `Two different verb definitions refer to` ‹name›
- `There is no previous grammar for the verb` ‹name›
- `There is no action routine called` ‹name›
- `No such grammar token as` ‹text›
- `'=' is only legal here as 'noun=Routine'`
- `Not an action routine:` ‹name›
- `This is a fake action, not a real one:` ‹name›
- `Too many lines of grammar for verb: increase #define MAX_LINES_PER_VERB`
- `'/' can only be used with Library 6/3 or later`
- `'/' can only be applied to prepositions`
- `The 'topic' token is only available if you are using Library 6/3 or later`
- `'reverse' actions can only be used with Library 6/3 or later`

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

- `'Ifnot' without matching 'If...'`
- `'Endif' without matching 'If...'`
- `Second 'Ifnot' for the same 'If...' condition`
- `End of file reached in code 'If...'d out`
- `This condition can't be determined`

“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

- `You can't 'Replace' a system function already used`
- `Must specify 0 to 3 local variables for 'Stub' routine`
- `A 'Switches' directive must come before the first constant definition`
- `All 62 properties already declared`
- `'alias' incompatible with 'additive'`
- `The serial number must be a 6-digit date in double-quotes`
- `A definite value must be given as release number`
- `A definite value must be given as version number`
- `Grammar__Version must be given an explicit constant value`
- `Once a fake action has been defined it is too late to change the grammar version. (If you are using the library, move any Fake_Action directives to a point after the inclusion of "Parser".)`
- `The version number must be in the range 3 to 8`
- `All 64 abbreviations already declared`
- `All abbreviations must be declared together`
- `It's not worth abbreviating` ‹text›
- `'Default' cannot be used in -M (Module) mode`
- `'LowString' cannot be used in -M (Module) mode`

· · · · ·

#### 11. Linking and importing

- `File isn't a module:` ‹name›
- `Link: action name clash with` ‹name›
- `Link: program and module give differing values of` ‹name›
- `Link: module (wrongly) declared this a variable:` ‹name›
- `Link: this attribute is undeclared within module:` ‹name›
- `Link: this property is undeclared within module:` ‹name›
- `Link: this was referred to as a constant, but isn't:` ‹name›
- `Link:` ‹type›`` ‹name›`in both program and module`
- `Link:` ‹name›`has type` ‹type›`in program but type` ‹type›`in module`
- `Link: failed because too many extra global variables needed`
- `Link: module (wrongly) declared this a variable:` ‹name›
- `Link: this attribute is undeclared within module:` ‹name›
- `Link: this property is undeclared within module:` ‹name›
- `Link: this was referred to as a constant, but isn't:` ‹name›
- `Link: module and game use different character sets`
- `Link: module and game both define non-standard character sets, but they disagree`
- `Link: module compiled as Version` ‹number›`(so it can't link into this V`‹number›`game`
- `'Import' cannot import things of this type:` ‹name›
- `'Import' can only be used in -M (Module) mode`

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

- `Opcode specification should have form "VAR:102"`
- `Unknown flag: options are B (branch), S (store), T (text), I (indirect addressing), F** (set this Flags 2 bit)`
- `Only one '->' store destination can be given`
- `Only one '?' branch destination can be given`
- `No assembly instruction may have more than 8 operands`
- `This opcode does not use indirect addressing`
- `Indirect addressing can only be used on the first operand`
- `Store destination (the last operand) is not a variable`
- `Opcode unavailable in this Z-machine version:` ‹name›
- `Assembly mistake: syntax is` ‹syntax›
- `Routine contains no such label as` ‹name›
- `For this operand type, opcode number must be in range` ‹range›

· · · · ·

#### 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:

- `This version of Inform is unable to produce the grammar table format requested (producing number 2 format instead)`
- `Grammar line cut short: you can only have up to 6 tokens in any line (unless you're compiling with library 6/3 or later)`
- `Version 3 limit of 4 values per property exceeded (use -v5 to get 32), so truncating property` ‹name›
- `The 'box' statement has no effect in a version 3 game`
- `Module has a more advanced format than this release of the Inform 6 compiler knows about: it may not link in correctly`

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

- `more modern to use 'Array', not 'Global'`
- `use '->' instead of 'data'`
- `use '->' instead of 'initial'`
- `use '->' instead of 'initstr'`
- `ignoring 'print_paddr': use 'print (string)' instead`
- `ignoring 'print_addr': use 'print (address)' instead`
- `ignoring 'print_char': use 'print (char)' instead`
- `use 'word' as a constant dictionary address`
- `'#a$Act' is now superseded by '##Act'`
- `'#n$word' is now superseded by ''word''`
- `'#r$Routine' can now be written just 'Routine'`
- `all properties are now automatically 'long'`
- `use the ^ character for the apostrophe in` ‹dictionary word›

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.