Module 1e, Learning the basic concepts of GeoDMS, reading errors and debugging

learning objective: learning how to read GeoDMS error messages and how to debug a configuration systematically
introduction
In the previous modules you wrote your first expressions, and you have probably already produced your first red items. That is normal: errors are part of everyday modelling work, and the GeoDMS gives you a lot of information to find and fix them. Reading that information well is a skill of its own. This module makes it explicit.
One thing to keep in mind throughout: the GeoDMS is declarative. A configuration file is not a script that runs from top to bottom. Items are only calculated when they are needed, for example when you open them in a view. As a consequence, most errors do not appear when the configuration is loaded, but at the moment an item is first used.
anatomy of an error
When something goes wrong, the GeoDMS shows it in several places:
- The TreeView: the failing item turns red. Recent GUI versions (19.2 and later) use a red background colour for items whose calculation failed; older versions colour the item name itself.
- The Detail Pages: select the red item and open the General page. Two extra rows appear: FailState (in which phase the item failed, e.g.
MetaInfo FailedorPrimary Data Derivation Failed) and FailReason (the actual error message). This is the first place to read the full message. - An error dialog: for blocking errors a dialog pops up with the message and the buttons Ignore, Terminate and Reopen. Reopen is handy: fix the configuration file in your text editor, save it, and reopen directly from the dialog.
- The EventLog at the bottom of the GUI: errors and warnings appear here in the stream of progress messages.
Errors travel along the dependency tree. If item A fails, every item calculated from A fails too. So the red item you happen to be looking at is often not where the mistake is: the message you see there may have been passed on from a supplier. Walk back to the first failing supplier before you start changing anything. The GeoDMS GUI automates this: right-click the red item in the TreeView and choose
- Step up to FailReason (F2): jump to the first failed supplier of this item.
- Run up to Causa Prima (Shift+F2): repeat that step until you reach the item where the error originates.
the most common beginner errors
Below are the errors you are most likely to produce in your first weeks, each with a broken snippet, the message to expect, and the fix. The exact wording and layout of messages can differ slightly per GeoDMS version; the quoted fragments are the stable parts to recognise.
syntax errors
A configuration file with a syntax error cannot be parsed at all, so nothing loads. The most common cause: a missing ;.
unit<float32> meter := baseunit('m', float32);
unit<float32> km := 1000.0 * meter // <- missing ;
unit<uint32> city : nrofrows = 4;
The parser reports where it got stuck, with the file name, the line and column number, and a ^ marker under the position:
item terminator ';' expected after item definition
C:/prj/debugging/cfg/debugging.dms(4,1) at
unit<uint32> city : nrofrows = 4;
^
Note that the reported position is where the parser noticed the problem, which is usually just after the actual mistake: here it points at the next item, while the ; is missing at the end of the previous one. Related messages from the same family: item definition or block terminator '}' expected (unbalanced curly braces) and string terminator expected (unclosed quote). Fix the syntax error, save, and reopen; only then can any other error appear.
unknown item name: reference outside scope
container results
{
attribute<km> dist_copy (city) := dist; // dist is a subitem of city
}
The message contains the name as you wrote it in the expression:
Cannot find dist
Remember the namespace rules from Module 1a, Learning the basic concepts of GeoDMS, naming items and namespaces: a name in an expression is searched in the item’s own context and its parent items, not in sibling subtrees. dist is a subitem of city, so from results you need the path:
attribute<km> dist_copy (city) := city/dist;
The same Cannot find message appears for a simple typo in an item name, so check the spelling first.
value type mismatch: cannot find operator
The GeoDMS does not convert value types implicitly. Dividing a uint32 attribute by a float32 attribute fails:
attribute<uint32> inhabitants (province);
attribute<float32> surface (province);
attribute<float32> density (province) := inhabitants / surface;
div Error: Cannot find operator for these arguments:
arg1 of type DataItem<UInt32>
arg2 of type DataItem<Float32>
Possible cause: argument type mismatch. Check the types of the used arguments.
The message lists the value type of each argument, which tells you exactly which argument to convert. Fix it with an explicit conversion function:
attribute<float32> density (province) := float32(inhabitants) / surface;
unit metric mismatch
From Module 1b, Learning the basic concepts of GeoDMS, understanding units you know that values units carry a metric, and that the GeoDMS checks your calculation logic with it. If the declared values unit does not match what the expression produces:
unit<float32> meter := baseunit('m', float32);
unit<float32> km := 1000.0 * meter;
attribute<km> dist (city);
parameter<meter> total_distance := sum(city/dist); // sum of km values is in km, not meter
the item fails with a message of this form (both units are shown with their full name, metric and value type):
Values mismatch between the specified ValuesUnit (...) and
the values unit of the calculation results (...) (incompatible Metrics)
Two possible fixes: declare the item with the values unit the calculation actually produces (parameter<km>), or convert explicitly. Since km and meter are based on the same base unit, the value function converts between them, including the factor 1000:
parameter<meter> total_distance := sum(city/dist)[meter];
domain mismatch
From Module 1c, Learning the basic concepts of GeoDMS, calculations over multiple domains you know that attributes can only be combined directly if they share the same domain unit. Mixing domains fails:
attribute<float32> visitors (shop);
attribute<float32> visitors_plus (city) := shop/visitors + 10f; // result has domain shop, not city
Domain mismatch between the specified Domain (...) and
the domain of the results of the calculation (...)
A close relative appears when the two arguments of an operator have different domains, for example city/dist * shop/visitors:
Domain mismatch between Domain of first argument (...) and
Domain of second argument (...)
The fix depends on your intent: correct the declared domain unit if it was simply wrong, or, if you really want to combine data from two domains, first relate them with a relation and functions like lookup or aggregation functions, as explained in Module 1c.
missing or wrong storage file
unit<uint32> province
: StorageName = "%ProjDir%/data/provinces.shp"
, StorageType = "gdal.vect"
, StorageReadOnly = "True";
If the file does not exist at the expanded location, the storage manager reports it, for example (for GDAL-based storages):
GDAL Error: cannot open dataset C:/prj/debugging/data/provinces.shp
or Failed to open ... for reading. Two things to check:
- The message shows the expanded path: placeholders like
%ProjDir%have been replaced. Verify that this expanded path is where your file actually is. The Source descr tab of the Detail Pages lists all files used for the selected item. - If the path is right but the declared attributes do not match the file contents (wrong attribute name, wrong value type), you get a read error instead. Check the storage-specific pages from Module 2A for the correct configuration per format.
In recent GUI versions a red database badge on the TreeView item also signals a read error on an external source.
a systematic debugging workflow
When the error is not obvious from the message alone, work systematically instead of changing things at random:
- Read the whole message. GeoDMS messages are wordy but precise: they name the items, units, value types and files involved. Most errors are solved by reading the message twice.
- Find the origin. Use Step up to FailReason (F2) and Run up to Causa Prima (Shift+F2) to walk to the item where the error actually occurs. Fix that one first; the downstream errors usually disappear with it.
- Update items bottom-up. Select a supplier of the failing item in the TreeView and update it separately: Update TreeItem (Ctrl+U) or Update Subtree (Ctrl+T) from the pop-up menu. Then open it in a table or map view and check whether the intermediate values are what you expect. Working upward from the sources, the first item with wrong or missing values marks the broken step.
- Inspect individual values. In a Table View, double-click a cell to open the ValueInfo window: it traces how that one value was calculated, step by step, back to the source data.
-
Make a small test item. Next to a suspect expression, configure a temporary item that calculates only a part of it:
// suspect: attribute<float32> result (city) := f(a) / g(b); attribute<float32> test_f (city) := f(a); attribute<float32> test_g (city) := g(b);View both in a table. This splits one hard question (why is
resultwrong?) into two easy ones. Remove the test items when you are done. - Use the code analysis tools. Via the main menu (Tools > Code analysis…) or the TreeView pop-up menu you can mark items for dependency analysis: set source (Alt+K) highlights all items that use the selected item, set target (Alt+B) highlights all items needed to calculate it. With add target (Alt+N) you add extra targets, and clear target resets the selection. The involved items are indicated in the TreeView. This is a quick way to see how an error can propagate, and which suppliers to inspect.
- Watch the EventLog. Warnings that do not fail an item still show up here, and they often explain surprising results. Use the filter tools to select message categories or to filter on a text part.
- Keep the edit-reload loop short. Open in Editor (Ctrl+E) opens the configuration file of the selected item in your text editor, at the right file. After saving your fix, Reopen current Configuration (Alt+R) reloads it and reactivates the item you were looking at.
debugging indirect expressions
Once you start using templates and indirect expressions (Module 3, Meta scripting ‐ templates and for_each), debugging gets one extra layer: an error message refers to the generated direct expression, not to the indirect expression as written in your file. The first thing to check is then General > CalculationRule in the Detail Page, which shows the generated expression. Module 3 has a dedicated be aware: debugging box on this, and the main wiki page error tracking in indirect expressions works out a real-world example.
try it yourself!
Save the following configuration as debugging.dms in a folder of your choice and open it in the GeoDMS GUI:
container debugging
{
unit<float32> meter := baseunit('m', float32);
unit<float32> km := 1000.0 * meter
unit<uint32> city : nrofrows = 4
{
attribute<string> name : ['Amsterdam', 'Rotterdam', 'Den Haag', 'Utrecht'];
attribute<km> dist : [45.0, 78.0, 62.0, 21.0];
}
unit<uint32> shop : nrofrows = 3
{
attribute<string> name : ['bakery', 'butcher', 'grocer'];
attribute<float32> visitors : [120.0, 80.0, 260.0];
}
container results
{
attribute<km> dist_copy (city) := dist;
parameter<meter> total_distance := sum(city/dist);
attribute<float32> visitors_plus (city) := shop/visitors + 10f;
}
}
This configuration contains four deliberate errors: one syntax error, one reference error, one metric mismatch and one domain mismatch. Find and fix them one by one:
- The syntax error blocks loading, so it surfaces first. Read the parser message, note that the reported position is just after the real mistake, and fix it.
- Reopen the configuration and open the three items under
resultsone by one (a table view for the attributes, double-click for the parameter). Each fails with one of the messages from this module. For every red item, read the FailReason on the General detail page and correct the configuration. Reopen with Alt+R after each fix. - When everything is fixed:
dist_copyshows the same values ascity/dist,total_distanceis206000(in meters) or206(if you declared it in km), andvisitors_plusshows130, 90, 270.
Try it yourself first; the fixes are listed below.
Solution: (1) add the missing ; after unit<float32> km := 1000.0 * meter. (2) dist is not visible from results; use the path city/dist. (3) sum(city/dist) produces a value in km; declare parameter<km>, or keep parameter<meter> and convert with sum(city/dist)[meter]. (4) shop/visitors + 10f has domain shop; declare visitors_plus with domain (shop) instead of (city).
Go to previous module: Module 1d, Learning the basic concepts of GeoDMS, classifying and visualising data
Go to next module: Module 2, Loading and storing data sources