16. Troubleshooting

Questions in the order people ask them on the SWMM forums, answered for AquaSWMM. Where the answer is the engine's behaviour the manual cites the EPA document; where it is a forum finding the thread is linked and paraphrased, never copied. Engine error numbers are indexed in Appendix C.

16.1 The continuity error: what it means and what is acceptable

The report ends each of Runoff Quantity Continuity, Flow Routing Continuity, Quality Routing Continuity and Groundwater Continuity with a Continuity Error (%) line: the mismatch between what came in and what went out plus what is stored, as a percentage of the inflow. AquaSWMM shows the largest absolute value in the run panel as worst continuity.

A model can run and be wrong. runswmm exits 0 regardless, and a finished run with a 40 % continuity error is still a finished run. The forum's own words for this are that SWMM lets a model silently fail (r/civilengineering). Always read the number.

Working thresholds from the OpenSWMM threads (4223, 3925): under 1 % is good; under 2 % is usually fine; 5 % needs a reason; anything above that means the routing did not converge somewhere and the results at that place are not trustworthy. Some reviewers ask for 0.5 %. The sign is only which side the imbalance fell on; a negative error is not better than a positive one (11479).

Where it comes from, in the order to check:

  1. Routing time step too long for the shortest conduit or steepest pipe (RM II §3.4, §4.4). Halve ROUTING_STEP, or set VARIABLE_STEP (0.5–0.75) and a MINIMUM_STEP.
  2. Very short links next to long ones; use LENGTHENING_STEP (10–30 s is a common setting) or merge them.
  3. Weirs and orifices on a junction with no surface area: a junction whose only outgoing links are a weir or orifice has nowhere to put water below the crest, so it fills and floods at low flow (28820). AquaSWMM's validator warns about this. Make the node a storage unit with a real area.
  4. Storage with a throttled outlet under SURCHARGE_METHOD EXTRAN (14273, USEPA #210); try SLOT, and check MIN_SURFAREA.
  5. Pumps cycling on and off each step; see §16.9.
  6. Flooding with ALLOW_PONDING NO: water lost to flooding is accounted as Flooding Loss, not an error — but a huge flooding loss with a small error is its own warning sign.

The engine prints only the five worst nodes in Highest Continuity Errors and the five worst links in Highest Flow Instability Indexes (USEPA #32). The Run Status window (§9.4) shows every entry the report carries, colours each continuity section green below 1 %, amber to 10 % and red above, and selects a listed node or link on click; the Model Report keeps the whole report text.

16.2 The run "worked" but nothing is right

Check, in order: the ERROR/WARNING lines in the run panel; the continuity error; the Node Flooding Summary and the Conduit Surcharge Summary in Tables; then the Profile with Max HGL along the trunk. A model whose every node floods is telling you about an offset or a unit, not about drainage.

A continuity error of -nan(ind), nan or inf is not a large error; it is no answer at all. The solution blew up, and the results file beside it holds numbers that mean nothing — outfall peaks in the millions of cfs, "flooding loss" of infinity. AquaSWMM marks such a run not valid in red (§9.4). Reports from other front ends carry the same line and nothing else to warn you; aquaswmm-swmm report on an old .rpt prints NOT VALID for one. The usual cause is an input error that stretches the model out of shape — offsets in the wrong convention (§16.6) top the list — rather than a time step that is merely too long.

16.3 Instability: "the results oscillate"

An oscillating hydrograph, a link with a large instability index, or a step count that never converges (% of Steps Not Converging in the Routing Time Step Summary) is a numerical problem, not a hydraulic one. RM II §3.4 is the reference. What people report helping, in rough order of effect (2346, 3938, 25086):

Kinematic wave is faster and cannot surcharge or back up; if your model has surcharge, backwater or loops it needs DYNWAVE (RM II §2.2).

16.4 Surcharged, flooded, or ponded

Three words the engine uses with exact meanings (UM §3.3 and the Node Surcharge and Node Flooding summaries):

SurDepth (surcharge depth) is an extra height above the rim before flooding is declared — a sealed manhole cover.

16.5 ERROR 209 and other "undefined object" errors

ERROR 209: undefined object X at line N means a row names an object that does not exist. The usual culprits (16685, 13117, USEPA #171):

AquaSWMM's validator catches all of these before the run (link "…" does not exist, rain gage "…" does not exist, outlet "…" is neither a node nor a subcatchment, to node "…" does not exist) and refuses to run until they are fixed, and its delete and rename commands keep references in step so they do not arise from editing here. They arise from files edited elsewhere. Click the finding to go to the row.

Also fatal at read time: a duplicate name (the engine ignores case, so J1 and j1 are the same object — the validator says so), a row with too few fields, a zero or negative length (ERROR 111) or area (ERROR 211), a REPORT_STEP shorter than ROUTING_STEP (ERROR 195), an outfall with more than one link (ERROR 141), an end date before the start (ERROR 191). The validator checks each of these and names the engine's code.

16.6 Offsets, inverts and rims: what the engine silently changes

A link's InOffset and OutOffset are the heights of its ends above the node inverts when LINK_OFFSETS DEPTH, or absolute elevations when ELEVATION (UM §3.3, Appendix D [CONDUITS]). The forum history says the manual's first definition was unclear and people still get it backwards (3507, 9489).

Two things the engine does without asking, noted only by a WARNING line in the report that is easy to miss (swmm5.org):

AquaSWMM's validator flags a negative offset and an ELEVATION offset below the node invert before the run; the profile draws what the engine will use (chapter 11). A drop through a structure is a pipe entering above the node invert — an InOffset on the downstream pipe's upstream end is not how to say that; put the offset on the incoming pipe's OutOffset.

The whole-model version of this is offsets written in one convention and labelled the other — typically by an export or a script. Every pipe end in a DEPTH model then carries its node's elevation as its offset: a pipe at a manhole with invert 864 ft sits 794 ft above it, the engine stretches all the manholes to reach (hundreds of WARNING 02 lines), and the run blows up. The validator recognises the pattern — most conduit offsets within 15 % of their own node's invert elevation, or, in an ELEVATION model, most offsets a small depth far below it — and reports it once, as an error on [OPTIONS] LINK_OFFSETS, with an example and the fix, ahead of the per-offset lines. The fix is the keyword, not the numbers: set LINK_OFFSETS to what the numbers already are with Convert existing offsets unticked, then switch again with it ticked if you want the other convention. Models on a local datum near zero cannot be told apart this way and are not checked.

Switching LINK_OFFSETS between DEPTH and ELEVATION is the same trap in miniature: the keyword alone changes what every offset in the file means, and every pipe moves. The Options dialog says so beside the field and offers Convert existing offsets with the node inverts (same undo step) (§8.2). Take it unless the numbers are already in the new convention.

16.7 I changed the flow units and the results changed

Changing FLOW_UNITS changes how every number in the file is read, and converts none of them (4235, 32845). The engine does the same: the labels change, the numbers do not. When you change the keyword in Project → Options…, AquaSWMM opens the unit-switch wizard (§8.2): it lists the groups below with the number of rows each would touch, converts the ones you tick as one undo step, and can copy its report. Anything it does not cover you convert by hand or with Replace in column → Scale (§6.4). The checklist of what a switch between U.S. and SI touches:

Section What must change
[JUNCTIONS], [OUTFALLS], [STORAGE], [DIVIDERS] elevations and depths: ft ↔︎ m
[CONDUITS] length ft ↔︎ m; offsets; Roughness is Manning's n and is the same in both systems
[XSECTIONS] every Geom column ft ↔︎ m
[SUBCATCHMENTS] area ac ↔︎ ha; width ft ↔︎ m
[SUBAREAS] depression storage in ↔︎ mm
[INFILTRATION] Horton rates in/hr ↔︎ mm/hr; Green-Ampt suction in ↔︎ mm, conductivity in/hr ↔︎ mm/hr
[RAINGAGES] and their series in/hr ↔︎ mm/hr, or in ↔︎ mm for VOLUME
[INFLOWS], [DWF] baseline flows and any FLOW series in the flow unit
[PUMPS] curves head ft ↔︎ m, flow in the flow unit
[WEIRS] Qcoeff dimensional: 3.33 (U.S.) ↔︎ 1.84 (SI) for a sharp-crested transverse weir; the engine expects the metric form in an SI model (3620)
[ORIFICES] Qcoeff dimensionless — unchanged
[STORAGE] curves and [CURVES] depth ft ↔︎ m; area ft² ↔︎ m²; flows
[DIVIDERS] cutoff flows, tabular curves flow unit
[OPTIONS] MIN_SURFAREA ft² ↔︎ m²
[LID_CONTROLS], [LID_USAGE] thicknesses in ↔︎ mm; areas ft² ↔︎ m²
[EVAPORATION], [TEMPERATURE], [SNOWPACKS] in/day ↔︎ mm/day, °F ↔︎ °C
[LOADINGS], pollutant concentrations usually unchanged (mg/L) — check

The storm-sewer design panel refuses metric models rather than convert (§12.2).

16.8 Subcatchment width

Width is the width of the overland flow path: conceptually the subcatchment's area divided by the length of the longest overland flow path to the collector (RM I §3.8). It sets the runoff hydrograph's timing; the same area with half the width peaks later and lower. Its estimation is the most-asked question on the forums (3818, 4862, 11520) and Guo (2012) called it a frequent source of user error. Rules of thumb people use: area ÷ maximum overland flow length; for a rectangular lot draining to a gutter along one side, the length of that side; for a subcatchment draining to a pipe running through it, about twice the pipe length (flow comes from both sides), with a skew factor when the two sides are unequal. Flow lengths over about 500 ft of true sheet flow are rare.

The design mapping uses Area / Width as the flow length for Kirpich (§15.3), so a wrong width also moves the design Tc. The validator warns when a width is zero: no runoff leaves such a subcatchment.

16.9 Pumps cycle on and off; control rules are rejected

A Type 2 pump (flow versus wet-well depth, stepwise) starts at Startup and stops at Shutoff depth; with the two close together and a small wet well it cycles every step and the continuity error climbs (2773). Separate the depths, enlarge the wet well, or use a Type 3 or 4 curve.

ERROR 2xx: … clause invalid or out of sequence in [CONTROLS] is nearly always a second IF inside one rule: every IF needs its own RULE name line (9552, 16749). The syntax is UM Appendix C. AquaSWMM does not parse rules; it patches object names in them on rename.

16.10 Rain and time-series files: ERROR 363, GHCN names, long comments

ERROR 363: invalid data in rain gage file (or in a time-series file) means the engine's reader could not parse a line (r/stormwater). The file formats are UM §11.5. Common causes: a header line the format does not allow, a blank line, a date in the wrong order, a station name over 50 characters in a GHCN download (USEPA #224), a comment line long enough to overflow the reader's buffer (USEPA #165), or an interval that does not match the gage's Interval. Bring the data into a [TIMESERIES] instead with Project → Time Series → Import… (§8.5): it detects the delimiter and date format, reads a GHCN-Daily station csv directly (and cuts the over-long station name to SWMM's limit, saying so), and can make the gage with a matching format and interval. The engine's own parser then reads the series with the model and any problem is reported with a line number. Export to File… goes the other way for series too long for the .inp, writing exactly the file format the engine expects.

WARNING 09: time series interval greater than recording interval means the gage's Interval is shorter than the series' spacing; set them equal.

16.11 Hotstart: ERROR 335, and when to regenerate

A hotstart file ([FILES] SAVE HOTSTART x.hsf then USE HOTSTART x.hsf) carries the end state of one run into the start of another (UM §11.6). It is binary, model-specific, and has no checker. ERROR 335: error reading hotstart file means the file was made by a model with a different object count or order — any add or delete since it was saved (19483, USEPA #214). Regenerate it after every structural edit; there is no way to inspect it. AquaSWMM does not manage hotstart files; the [FILES] lines are text in the Options dialog.

The common uses: a warm-up run of a day or two of dry weather to fill the pipes and wet wells before the event, and a tidal outfall's initial condition.

16.12 Nothing is on the map, or it is in the wrong place

16.13 Two engines disagree, or the design panel disagrees with SWMM

Different engine versions give different numbers, because bugs were fixed: 5.0 → 5.1 changed evaporation and infiltration accounting; 5.1 → 5.2 fixed elliptical-pipe geometry, changed the inlet handling, and more (4769, USEPA #144; EPA's own change lists are at epa.gov). A calibrated model is calibrated to an engine. Results → Compare Engines… shows the difference object by object, and every AquaSWMM run and report carries the engine version and binary hash so a number can be tied to the binary that produced it.

The same version can disagree with itself. PCSWMM reports "Build 5.2.4" but runs its own compiled library, not EPA's runswmm.exe; the floating-point order differs, and THREADS above 1 adds more. A healthy model shrugs that off: a PCSWMM 1D-2D model run here matched its PCSWMM report in every peak flow, depth and outfall, with 57 of 246 2D cells differing by under 0.0001 ft. A model already near its limits does not: a 12,000-cell 1D-2D model with 4 % of time steps not converging matched PCSWMM in every total — outflow, flooding, continuity — while 12 % of its 2D cells and 19 % of its coupling links peaked differently, some by half. That spread is the model telling you how much its local peaks can be trusted; tighten the time step and fix the non-converging nodes before reading one to two decimals. AquaSWMM hands the engine the file unchanged — the EPA sample models produce byte-identical results through AquaSWMM and through runswmm directly.

To check a model someone ran elsewhere: run its .inp here, then in Compare Runs press Add results from file… and pick their .out (read in place; the .rpt and .inp beside it are used for the engine version and the model hash). From a script, aquaswmm-swmm compare their.out ours.out --inp model.inp splits the differences into 1D, 2D and coupling (§9.7).

The storm-sewer design panel and the SWMM run will not agree on peaks either, and should not: one is a Rational peak at one intensity, the other a routed hydrograph under a hyetograph. Typical reasons for a 2× gap (r/Hydrology): the Rational Tc floor; a subcatchment width that gives a very different time to peak; a WET_STEP or rain interval too coarse for a small catchment; storage or surcharge attenuating the SWMM peak. Use the design panel to size and check; use the run to see what the sized system does.

16.14 The model is slow

Runtime is the routing step count times the network size. Continuous models with LID controls are the usual complaint (5464); THREADS in Options uses more cores for the routing; REPORT_STEP does not change runtime but changes the .out size; DRY_STEP can be long. Stop ends a run that is taking too long and keeps what it wrote so far (chapter 23), but still check the dates before pressing F5.

The editor itself is built for PCSWMM 1D-2D models with tens of thousands of objects. On one with about 13,000 junctions and 37,000 conduits, the model opens in under half a second, a map frame takes about 50 ms, and the attribute table only builds the rows on screen, so scrolling a 37,000-row table is as quick as scrolling a short one. Select All and band selection on such a model stay quick. If the editor is slow on a model this size or smaller, that is a bug: report it with the model's object counts.

The same holds with ARM on top: a PCSWMM 1D-2D model with 20,000 junctions, 54,000 conduits and 20,000 ARM subcatchments. On it:

What makes that possible, and what you will see of it:

16.15 Crashes, and where unsaved work is

The engine runs as a separate process: an engine crash cannot take the editor down, and the run is reported as failed with the report's last lines. If AquaSWMM itself stops, the model on disk is whatever you last saved, plus the autosave snapshot: while the model is dirty its text is written every N minutes (Run → Autosave every N min, default 2) to <model>.inp.autosave beside the file, or to %APPDATA%\AquaSWMM\recovery for a model that has no file yet. On the next open of that file AquaSWMM asks Recover unsaved changes? with the file's and the snapshot's timestamps: Restore autosave or Discard it, keep the file. Saving or closing the model removes the snapshot. Ctrl+S is still cheap and lossless.

16.16 Non-ASCII characters in the path

The stock EPA engine can fail to open a model whose path contains characters outside ASCII (õ ä ö ü, CJK) — reported against the Windows build and the Python bindings (swmm-python #71, #70). AquaSWMM sidesteps it: a model on a non-ASCII path is run from a scratch copy under %TEMP%\AquaSWMM\run\<hash>\, with its [FILES] and data files copied beside it so relative paths still resolve, and the Run Status window says Ran a scratch copy and names the path the engine read (§9.2). The .rpt and .out are beside the copy, and the run history, Compare Runs and the Python terminal use that location. Only the engine sees the copy; your model stays where it is.

16.17 What the validator checks

Live, on every edit, shown under the map and in Project → Validate Model. Errors refuse a run; warnings do not.

Errors: a link whose from/to node does not exist; a subcatchment whose outlet is neither a node nor a subcatchment, or whose rain gage does not exist; a duplicate name within a section, across the node sections or across the link sections, including names that differ only by case; a conduit without an [XSECTIONS] row; a row shorter than its section allows; [COORDINATES], [VERTICES], [POLYGONS], [SYMBOLS] or [XSECTIONS] rows for objects that do not exist; a zero or negative conduit length or subcatchment area; REPORT_STEP shorter than ROUTING_STEP; an outfall with more than one link, or with an outgoing link; a simulation that ends before it starts; conduit offsets that as a whole are in the other convention from LINK_OFFSETS (one finding on [OPTIONS], §16.6); a [REPORT] NODES, LINKS or SUBCATCHMENTS list that names an object the model does not have (ERROR 209); a line of 1,024 characters or more before any comment (ERROR 201).

Warnings: a node without coordinates; more than one coordinate row for a node; a node no link connects to; a rain gage no subcatchment uses; a negative offset, or an ELEVATION offset below the node invert (the engine silently uses 0 and raises the rim if it must — WARNING 03); a subcatchment width of zero; a curve or series with no points; a junction whose only outgoing links are weirs or orifices; DRY_STEP shorter than WET_STEP (the engine raises it — WARNING 06); a model with nodes, links or subcatchments but no [REPORT] line naming them (or NONE). That run succeeds and writes a results file with none of that kind in it, so the map, charts and profile come up empty.

It does not check hydraulics, units, or anything inside [CONTROLS], [LID_CONTROLS], [STREETS] or the climate sections.