Diagnostics and error messages
The compiler reports every issue with an E##### code (e.g. E00221), a severity level, and a message — currently only in Spanish — with the concrete values interpolated.
Levels
| Level | Meaning |
|---|---|
error | Blocks code generation; the object doesn’t compile. |
warning | Doesn’t block compiling, but flags something probably unintentional (e.g. a variable declared and never used). |
What they look like
On the command line (human format):
[2026-07-24T21:26:47Z] ERROR E00221 (line: 12, column: 5): La variable 'x' declara char(16773105), fuera del rango permitido (1-16773104).
Or as JSON (--format json, the one the VSCode extension consumes to draw red/yellow underlines in the editor):
{"errors": [{"line": 12, "column": 5, "severity": "error", "message": "..."}]}
Some representative examples
| Code | Situation |
|---|---|
E00001 | A @Name section was expected and something else was found. |
E00128 | A file referenced by the .warpcfg (e.g. the SSH key in @Connection) doesn’t exist on this machine — doesn’t block validate/generate, but will be needed for build/reverse. |
E00148 | The field in field(...) was not found: for field(Field), in no table of @References/Tables; for field(Table.Field), because the table isn’t referenced or doesn’t contain that field. |
E00149 | The field in field(Field) is ambiguous: it exists in more than one table of @References/Tables; specify the table with field(Table.Field). |
E00152 | A variable from @Variables was declared but never used (warning). |
E00178 | A variable used in @Layout is not declared in the global scope of @Variables. Also reported when a &variable.member path points to a member that does not exist. |
E00179 | ‘&{arg}’ (an in parameter or a constant, read-only) cannot be passed to ‘{name}’, which modifies it internally (directly or indirectly). |
E00192 | {name}() can only be used inside an Event, Procedure or Function of a Screen (the cursor position only exists after the screen is read). |
E00195 | Invalid use of RefreshSelectRow()/For Each Row outside a Screen with a DataGridView. |
E00206 | String(): 2 to 4 arguments were expected (number, integers[, decimals][, fill]), {found} were found. |
E00210 | Two @Layout variables or paths truncate to the same DDS field (struct paths are flattened: . becomes _, uppercase, 10 characters; e.g. cust.Code and cust_Code). |
E00221 | char outside the allowed range for a standalone variable in @Variables (1-16,773,104). |
E00222 | number with precision out of range (1-63) in @Variables. |
E00223 | number whose scale is greater than its precision. |
E00224 | varchar outside the allowed range (1-16,773,100). |
E00237 | Member type not allowed in a struct template: only char/varchar/number/date/time/timestamp/field, struct(Template) and list(struct(Template)) are allowed (neither matrix nor list of scalar types). |
E00238 | struct(Name) references a template that doesn’t exist in @Variables; also reported for nonexistent templates inside members of another template and in list(struct(X)). |
E00240 | &Variable.Member access to a member that doesn’t exist in the struct’s template. |
E00242 | A struct(OtherTemplate) variable was passed where a different template was expected (the comparison is by exact name, not by structure). |
E00253 | The format of StringToDate/NumberToDate/IsDate/DateToString must be one of Iso/Usa/Eur/Jis/Mdy/Dmy/Ymd/Jul, or a text pattern with YYYY, MM and DD once each (e.g. "YYYYMMDD", "DD/MM/YYYY"; in DateToString, up to 10 characters). |
E00269 | A table’s Description (@Structure) exceeds the 50 characters allowed by TEXT in DDS. |
E00270 | A field’s Description (@Fields) exceeds the 50 characters allowed by TEXT in DDS. |
E00271 | An index’s Description (@Indexes) exceeds the 50 characters allowed by TEXT in DDS. |
E00278 | list has no such method (valid ones: Add, Clear, Init, Remove, Count, Split, Json). |
E00281 | The Description in @Properties (of a Program or Screen) exceeds the 50 characters allowed by TEXT in the compile-time CL commands (CRTBNDRPG/CRTDSPF/CHGPFM). Same limit and criterion as E00269/E00270/E00271. |
E00284 | @License Port is 0. |
E00285 | @License Host is not a valid host. |
E00286 | @License Fingerprint is not a valid SHA-256 fingerprint. |
E00287 | Warning: @License has Host but no Fingerprint. |
E00288 | Warning: @License has Host and File together (File is ignored). |
E00290 | @Connection/@Deployment/@License declared directly inside @GeneratorConfig, without wrapping them in a @Profile "Name". |
E00291 | @GeneratorConfig doesn’t declare any @Profile. |
E00292 | The profile requested with --profile or Default Profile doesn’t exist among the declared @Profiles (available ones are listed). |
E00293 | Several @Profiles are declared and it wasn’t indicated which one to use (neither --profile nor Default Profile), so the compiler can’t pick just one (available ones are listed). |
E00294 | .Json() used as a standalone statement: it returns the JSON as a value and must be used in an expression (&text = &Person.Json()). |
E00295 | .Json() applied to a variable that is neither a struct nor a list. |
E00296 | A method other than Json was called on a struct (Json is the only valid method). |
E00297 | .Json() on a list whose element is neither a scalar type (char, varchar, number, date, time, timestamp) nor a struct. |
E00298 | A variable in the local scope is also declared in global; the name can’t be repeated because both scopes live at module level in the generated RPG. |
E00299 | The struct template ‘{template}’ contains itself (directly or indirectly) through its struct/list(struct) members. |
E00300 | The variable ‘{variable}’ would take {size} bytes, more than the maximum of an RPG variable (16773104): reduce the size of its members or of the lists it contains (a list inside a struct reserves 100 elements). |
E00301 | JsonSplit(): the first argument must be a char/varchar &Variable (or struct member), or a text literal; found {found}. |
E00302 | JsonSplit(): ‘&{variable}’ must be a list of char or varchar (the lines are stored there). |
E00303 | JsonSplit(): the indentation must be a number, found {found}. |
E00304 | The @Parameters parameter ‘&{variable}’ cannot be a list of that type or a matrix: only lists of char or varchar are supported (an array of text lines, ending at the first empty line). |
E00305 | {method}(): ‘&{variable}’ must be {expected} whose members are char, varchar, number or date, with a record of up to 32766 positions.{hint} |
E00306 | {method}() must be used as {where}. |
E00307 | {function}(): a char/varchar value or a list of char/varchar was expected, found {found}. |
E00308 | {function}(): ‘&{variable}’ must be a list(struct(…)). |
E00309 | {function}(): the {width}-position record does not fit in the elements of ‘&{variable}’ (char/varchar({element})). |
E00310 | The constant ‘{name}’ must be of type char, varchar or number. |
E00311 | The value of the constant ‘{name}’ is not valid for its type: {detail}. |
E00312 | The constant ‘&{variable}’ cannot be modified. |
E00313 | The @Parameters parameter ‘&{variable}’ cannot be a constant. |
E00314 | The constant ‘&{variable}’ cannot be displayed in a screen field: copy it to a variable. (In a printable Block of a Program it can be used.) |
E00315 | Table ‘{table}’ has no PrimaryKey in @Indexes: ‘Join In’ reads it by its primary key. |
E00316 | Join In {table}: primary key field ‘{field}’ ({key}) does not exist in the table being read or in the tables already joined. Use ‘On’ to say where each field comes from. |
E00317 | Join In {table}: the ‘On’ fields on the joined table side must be exactly its primary key fields ({key}), with none repeated or missing. |
E00318 | Join In {table}: field ‘{field}’ ({target_type}) does not accept ‘{source}’ ({source_type}). |
E00319 | Field ‘{field}’ belongs to table ‘{table}’ joined with ‘Join In’ and is read-only: it cannot be assigned. |
E00320 | Style: ‘{name}’ is not a known color or attribute. Colors: Green, White, Red, Blue, Yellow, Pink, Turquoise. Attributes: Reverse, High, Underline, Blink, Hidden. |
E00321 | Style: only one color per Style is allowed; found ‘{name}’ in addition to ‘{previous}’. |
E00322 | Invalid condition in @Layout: only variables, numbers, strings, comparisons, And/Or/Not and Function() calls without arguments are allowed. |
E00323 | Too many Style entries on the same element: at most one unconditional and three conditional ones are allowed. |
E00324 | Style has no color or attribute: give at least one (for example Style(Red) or Style(Reverse)). |
E00325 | Style is only allowed in a Screen. |
E00326 | Exit is only valid inside a loop (For Each, For Each Row, For or While). Inside a Procedure, Function or Event, the loop must be in the same body. |
E00327 | ‘{keyword}’ is a reserved word that is only valid inside a ‘Do Case’ (Do Case / Case <condition> / Otherwise / EndCase). |
E00328 | Round(): expected 2 arguments (expression, decimals), found {found}. |
E00329 | Round(): ‘decimals’ must be an integer literal between 0 and {max} (a compile-time constant: it defines the scale of the result). |
E00330 | Round(): the first argument must be of type Number (found {type}). |
E00344 | The key text of event ‘{event}’ cannot be empty or longer than {max} characters. |
E00345 | Event ‘{event}’ has the same name as a Procedure or Function in this file; both generate a subprocedure with that name. Rename one of them. |
E00331 | SetFocus() is only valid in a Screen. |
E00332 | SetFocus(): ‘&{variable}’ is not the variable of any Input in @Layout. |
E00333 | SetFocus() takes no arguments ({found} given). |
E00334 | SetFocus() is a statement: it returns no value and cannot be used inside an expression. |
E00335 | Refresh is only valid in a Screen. |
E00336 | Cursor(): expected 1 argument (&variable), found {found}. |
E00337 | Cursor(): the argument must be a &variable. |
E00338 | Cursor(): ‘&{variable}’ is not the variable of any Input or DataGridView column in @Layout. |
E00339 | Table ‘{table}’ has no PrimaryKey in @Indexes: ‘When Duplicate’ re-reads the existing record by its primary key. |
E00340 | Field ‘{field}’ is part of the primary key of ‘{table}’: ‘When Duplicate’ cannot reassign it. |
E00341 | String(): the fill must be a literal text of a single character (for example “0” or “ “). |
E00342 | Int(): 1 argument (a number) was expected, {found} were found. |
E00343 | Int(): the argument must be of type Number (found {type}). |
E00346 | Function Keys Row ({row}) is out of range: it must be between 1 and {max} (Rows - 1; the last row is kept for messages). |
E00347 | ‘{color}’ is not a valid color for function keys; use Green, White, Red, Blue, Yellow, Pink or Turquoise. |
E00348 | Screen size {rows}x{columns} is not valid: a 5250 only supports 24x80 or 27x132. |
E00349 | Record format ‘{name}’ is not valid: up to {max} characters, letters and digits only, starting with a letter. |
E00350 | The object name ‘{name}’ is not valid for IBM i: up to {max} characters, only letters and digits, and it must start with a letter. Rename the file (or the Name property). |
E00351 | Return without a value inside Function ‘{name}’: a Function must return a value (Return &variable or Return expression). |
E00352 | Function ‘{name}’ never returns a value: add at least one Return with a value. |
E00198 | LoadRow() can only be used inside an Event or a Procedure of a Screen (not in a Function, which is invoked as an expression). |
E00199 | Retired: LoadRow() no longer has to be inside a For Each. |
E00200 | Retired: there is no longer a limit of one For Each with LoadRow() inside Event Load. |
E00201 | The For Each that loads the DataGridView (with LoadRow()) must declare an Index: without one, there are no ordered fields to resume loading from when Page Down is pressed. |
E00353 | {element} ends at column {end}, but the screen has {max} columns: IBM i rejects the field or splits it across two rows. Shorten the text or the widths, or move the element to the left. |
E00356 | {scope} declares the local variable ‘{variable}’, which shadows the global variable of a DataGridView Column: LoadRow() would copy the local value. Rename the local variable. |
E00357 | The event name ‘{event}’ is not valid: it becomes a subprocedure name, so it only allows letters, digits and _ and must start with a letter. The text shown in the key row goes separately: Event ‘Name’ 6 “Text with spaces”. |
E00358 | {function}() expects {expected} argument(s), but received {found}. |
E00359 | {function}(): argument {arg} must be text (char or varchar), not {type}. |
E00360 | {function}(): argument {arg} must be numeric, not {type}. |
E00361 | {function}(): argument {arg} must be a literal: {rule}. |
E00362 | Mod(): argument {arg} cannot have decimals (RPG requires integers for %rem); use Int() to truncate it. |
E00363 | &{variable}.Split() only works on a list of char or varchar (each piece is text). |
E00364 | ‘EndTry’ is missing to close the ‘Try’ block. |
E00365 | The status code ‘{code}’ of ‘Catch’ is not valid: it must be a number between 100 and 9999 (program errors are 100-999 and file errors 1000-2999). |
E00366 | {function}() can only be used inside a ‘Catch’ block. |
E00367 | A ‘Try’ needs at least one ‘Catch’. |
E00368 | This ‘Catch’ never runs: an earlier ‘Catch’ without a filter (line {line}) already catches every error. Put the ‘Catch’ without a filter last. |
E00369 | Parameter ‘{variable}’ of @Parameters is used in @Layout and its name has 10 characters or fewer: in a Screen the DDS field takes that same name and RPG confuses it with the parameter (it does not compile on IBM i). Use a name longer than 10 characters. |
E00370 | {function}(): argument {arg} must be {expected}, found {type}. |
Each message has a code, a level (error/warning) and a template with the case’s actual details ({variable}, {length}, etc.) the compiler fills in when reporting it.
Message language
The compiler embeds its message catalogs in Spanish and English, with the same codes and the same template placeholders. The language is chosen with --lang (or -g):
warpgate --action validate --lang en
warpgate --action validate -g es
- If
--langis omitted, it is taken from theLANGenvironment variable (for examplees_PE.UTF-8selectses). - If
LANGdoes not name a real language (C,POSIXor empty),enis used. - An external
resources/messages_<language>.jsonfile next to the executable can override messages from the embedded catalog.
In VSCode, the language is controlled by the warpgate.language setting (see VSCode commands).
What the language covers
--lang does not only affect diagnostics with line/column (E*, W*). All user-facing text comes from the catalog and follows the selected language:
- CLI log lines for validation, generation, reverse engineering and deployment.
- Deployment progress and errors (
[Despliegue]in Spanish,[Deployment]in English): connecting, uploading, running, etc. - SSH/FTP/SFTP connection errors (for example, “no se pudo conectar” / “could not connect”) and transport errors.
- License messages: service denials, individual license, status (
license-status) and request (license-request). - Generation errors, such as
@Connectionor@Deploymentnot found.
These messages use the code series M00001-M00106 (in messages_es.json and messages_en.json). Unlike the E* codes, they carry no line or column.
A few internal code generator errors (invariants such as “validation should have caught this”) always remain in Spanish, as do texts coming from the operating system (for example, Connection refused (os error 111)).
When they fire
- On saving/opening a
.warpfile in VSCode (warpgate.validateOnSave/validateOnOpen), if there’s a.warprojresolved for that file. - Manually with
warpgate --action validate— never touches the IBM i, purely local. - License note:
validatedoes not require a license;generate/build/reversedo (see Licensing). - As part of
generate/build/reverse— if there are errors, code generation/deployment doesn’t proceed.