Symptom Signature and Failure Sequence
The project loads normally, and the console logs loadProject complete. The failure starts when you open the report's Design panel. The Designer finishes loading sample data, tries to rebuild the page template from its stored XML, and throws. After that, every tab switch in the report editor adds another exception. The report looks lost, but the template is still stored. It fails to deserialize because one numeric property holds a value the reader will not accept.
The console shows three exceptions in this order:
| Order | Exception | Location | Meaning |
|---|---|---|---|
| 1 | java.lang.ClassCastException: Error trying to coerce 'Infinity' to a number. |
TypeUtilities.toNumber called from AbstractXYChart.fromXML / TimeseriesChart.fromXML
|
Root cause. A chart property was saved as the string Infinity, and the loader cannot convert it back to a number. |
| 2 |
java.lang.NullPointerException with Unable to commit changes made to ...ReportResource
|
DesignerPanel.commitChanges |
Consequence. The design editor was never created, so the commit path dereferences a null editor. |
| 3 | java.lang.NullPointerException |
DesignerPanel.onDeactivate |
Consequence. The same null editor is hit again when the tab deactivates. |
Treat the NullPointerExceptions as noise. They are the reason many engineers search for the wrong thing. Every decision below keys off exception 1.
Check 1: Root Exception in the Console
Before anything else, open the Designer console and scroll to the first exception logged after loadProject complete. Ignore any exception that appears after you click a report tab.
- Open the report so the failure reproduces, then open the Designer console.
- Find the first
Exception in thread "AWT-EventQueue-..."block. - Read the exception class and message on its first line.
| First exception reads | Interpretation | Next check |
|---|---|---|
ClassCastException: Error trying to coerce 'Infinity' to a number. |
Non-finite double stored in the report template | Check 2 |
ClassCastException coercing some other string |
Same class of fault: a property serialized in a form the reader rejects. The procedure below still applies, but the offending value differs. | Check 2, looking for the literal named in the message |
Only NullPointerException in DesignerPanel, no coerce error |
The root exception scrolled out of view or went to a log file | Clear the console, reopen the report, and capture again |
The mechanism behind the coerce error is a mismatch between how the value is written and how it is read. A Java double can hold positive infinity. Converting it to text produces the literal Infinity, and the report archiver writes that text into the template XML without complaint. On load, the value goes through TypeUtilities.toDouble, then coerce, then toNumber, and that coercion path rejects Infinity. So the report saves fine and then fails to load. Do not move on until you have the coerce message in hand.
Check 2: Shape Class in the fromXML Frames
The stack trace names the shape that failed to deserialize. Read the frames just above the RXArchiver.fromXML recursion:
at com.inductiveautomation.ignition.common.TypeUtilities.toNumber(TypeUtilities.java:737)
at com.inductiveautomation.ignition.common.TypeUtilities.coerce(TypeUtilities.java:988)
at com.inductiveautomation.ignition.common.TypeUtilities.toDouble(TypeUtilities.java:1333)
at com.inductiveautomation.rm.shape.j2dshapes.AbstractXYChart.fromXML(AbstractXYChart.java:444)
at com.inductiveautomation.rm.shape.j2dshapes.TimeseriesChart.fromXML(TimeseriesChart.java:146)
at com.inductiveautomation.rm.archiver.RXArchiver.fromXML(RXArchiver.java:240)
...
at com.inductiveautomation.rm.shape.RMPage.fromXMLChildren(RMPage.java:774)
...
at com.inductiveautomation.reporting.common.resource.PageTemplate.getTemplate(PageTemplate.java:40)
at com.inductiveautomation.reporting.designer.workspace.design.DesignerPanel.createEditor(DesignerPanel.java:149)
Here the failing class is TimeseriesChart, which inherits its loader from AbstractXYChart. The value that fails is read in AbstractXYChart.fromXML through toDouble, so it is a double-typed property of the XY chart. That property is Bar Width.
This branch has a common trap. The last component added before the failure is usually blamed. In this case a pie chart was the last edit, but the trace points at an XY/timeseries chart. The pie chart only triggered a save and reload that exposed a bad value already sitting in the XY chart. Follow the trace, not the edit history.
The RMParentShape.fromXMLChildren and RMPage.fromXMLChildren frames show nesting. The chart sits on a page, and possibly inside a group or other parent shape. Count the repeated RXArchiver.fromXML recursion levels between RMPage and the chart. That tells you how deep the chart is nested, which helps you find it once the report opens again.
| Shape class in trace | Property family to inspect | Next check |
|---|---|---|
TimeseriesChart via AbstractXYChart
|
Bar Width on the XY chart | Check 3 |
| Any other shape class | Numeric properties of that shape. Look for values that grew unexpectedly or are bound to expressions. | Check 3, then inspect that shape instead |
Check 3: Clean Prior Copy of the Project
The fastest recovery skips the broken template entirely. Before restoring anything, export the current project as-is. That gives you the damaged artifact for vendor support and a fallback if a restore goes wrong. Then look for a copy saved before Bar Width went non-finite.
| Recovery source | What you lose | Confirm before restoring |
|---|---|---|
| Prior project revision (rollback) | Edits made after that revision | The revision predates the last save that included the infinite Bar Width |
| Project export file | Edits made after the export date | Import into a scratch project first and open the report's Design panel |
| Gateway backup | All gateway changes since the backup, not only this report | Restore to a test gateway, or pull only the project from it |
- Export the current (broken) project and keep it.
- Restore or import the candidate copy into a scratch project, not over the live one.
- Open the report and select the Design panel.
- Watch the console. If no coerce exception appears and the design canvas renders, the copy is clean. Go to the recovery procedure.
- If the coerce exception appears, the bad value was already saved in that copy. Try an older one, or go to Check 4.
If the clean copy is several hours old, keep it as your baseline anyway. Then work through Check 4 in parallel. A Designer build that loads the broken template recovers the newer work.
Check 4: Designer Build With the Infinity Fix
This defect was reproduced and fixed in the reporting module. The fix makes the loader accept an infinite bar width instead of throwing. In the build you are running, the broken template cannot be opened. In a build that includes the fix, the same template loads, and you can correct the property in the editor.
- Record the Ignition gateway version and the Reporting module version from the gateway status/modules page.
- Check the Inductive Automation release notes and changelog for a reporting fix covering XY chart Bar Width and
Infinitycoercion. No specific version is given here, so confirm the fixed release from the vendor's notes or through Inductive Automation support. - Upgrade a test gateway first. Restore a gateway backup or import the broken project export onto it.
- Open the report's Design panel on the test gateway. If it renders, the fix covers your case. Go to Check 5 before editing anything.
- If it still throws, send the exported broken project and the full console trace to Inductive Automation support.
Do not upgrade production only to recover one report without first proving the upgrade on a test gateway. Other modules and projects ride on the same upgrade.
If no fixed build is available to you, stop editing the report in the current Designer session. The Unable to commit changes error means edits made in the Design panel are not being committed to the resource. Work done in that state does not persist, and repeated saves only add confusion to the project history.
Check 5: Origin of the Infinite Bar Width
Once the report opens, you must find out how Bar Width reached infinity. If you only reset the value, the fault returns. There are three routes, and each has its own fix.
| Route | How to confirm | Prevention |
|---|---|---|
| Typed overflow: a digit string longer than a double can hold was entered in Bar Width | The property editor shows the infinity symbol with no binding on the property | Enter a sane finite width. The editor accepted the value and displayed the infinity symbol instead of rejecting it, so check the displayed value after every entry. |
| Binding: Bar Width driven by an expression or parameter that can evaluate to infinity | The property shows a binding. Evaluate the expression against sample data. | Guard the expression against division by zero and clamp the result to a finite range. |
Locale drift: the value grows each time the report round-trips through preview in a locale that uses , as the decimal separator |
Bar Width changes between Design → Preview → Design cycles with no manual edit | See the next section. |
The typed-overflow route is mechanical. A Java double tops out near 1.8 × 10308. Parse a longer run of digits, such as a 1 followed by a few hundred zeros from a held-down key, and the result is positive infinity, not an error. The property editor accepts it, displays the infinity symbol, and the archiver saves it. The damage stays hidden until the next load.
Read the property editor's current value, not your memory of what you typed. If it shows the infinity symbol, any save from that moment writes an unloadable template.
Locale Drift Across Preview Cycles
This is the route that catches engineers who never typed anything unusual. The same infinite Bar Width appeared on a machine using a comma-decimal locale, after roughly four hours of normal design work with frequent switching to preview. The value grows each cycle until it overflows.
The mechanism is the classic locale round-trip fault. Somewhere between the editor, the template serialization, and the preview render, the value is written with one decimal convention and parsed with another. When a comma-decimal value such as 1,5 is parsed by a reader that treats , as a thousands grouping separator, it comes back as 15. Each round trip can shift the value by one or more orders of magnitude. After enough preview cycles it passes the double limit, becomes Infinity, and the next save writes a template that will not load. The vendor fixed the Infinity handling first and tracked the localization issue as a separate defect. Treat them as two problems, because a build with only the Infinity fix still lets the width drift.
Confirm or rule out this route with a direct measurement:
- Select the XY chart and write down the exact Bar Width shown in the property editor.
- Switch to Preview, wait for the render, then switch back to Design.
- Read Bar Width again.
- Repeat three to five times.
| Observation | Meaning | Action |
|---|---|---|
| Value unchanged across all cycles | No locale drift in this build and locale | Typed overflow or binding was the cause. Fix at the source. |
| Value grows by a fixed factor each cycle | Locale round-trip fault active | Apply the locale workaround below. |
| Value changes only when data changes | Binding-driven | Fix the expression. |
Until you are running a release that resolves the localization defect, use one of these workarounds:
- Run the Designer under a locale that uses
.as the decimal separator. Change the OS regional format or the JVM locale used to launch the Designer, then repeat the drift measurement to confirm the value holds steady. - If you must stay in a comma-decimal locale, use whole-number widths so no decimal separator is involved, and re-run the drift measurement to confirm.
- Check Bar Width on every XY chart before each save during a long session. Treat any value that differs from what you set as a stop condition.
Reproduction on a Scratch Report
Before trusting a fix, whether an upgrade, a locale change, or a guarded binding, reproduce the failure on purpose in a throwaway report. That proves the test detects the fault, so a clean result afterward means something.
- Create a new scratch report in a test project.
- Drag an XY chart onto the page.
- Select Bar Width and enter a 1 followed by a long run of zeros. Holding the 0 key for several seconds works.
- Press Enter. Confirm the property editor shows the infinity symbol. If it shows a finite number, append more zeros and press Enter again.
- Save the report.
- Close and reopen the report, then select the Design panel.
| Result on reload | Build status |
|---|---|
ClassCastException coercing Infinity, followed by DesignerPanel NullPointerExceptions |
Build does not include the Infinity fix. Never let a production report reach an infinite width in this build. |
| Report opens and Bar Width shows the infinity symbol | Infinity fix present. Broken production templates will load, and you can correct them. |
For the locale variant, repeat the scratch test with a finite fractional Bar Width under a comma-decimal locale and cycle Design/Preview as in the drift measurement. If the value holds steady across cycles, the localization fix is present or your workaround is effective.
Recovery Procedure and Verification
This is the resolving branch. You now have one of two things: a clean prior copy from Check 3, or a Designer build that opens the broken template from Check 4. Carry out the steps in order. Each step lists the reading that confirms it.
- Preserve the broken artifact. Export the current project before any change. Confirm: the export file exists and has a non-zero size.
-
Open the report in a working environment. Use either the restored clean copy or the broken copy on a gateway that has the Infinity fix. Confirm: the Design panel renders the canvas, and the console shows no
coerce 'Infinity'exception and noDesignerPanel.commitChangesoronDeactivateNullPointerException. - Locate every XY chart. Walk each page, including charts nested inside groups (the nesting depth from Check 2 tells you how deep to look). Confirm: you have a list of every XY/timeseries chart in the report.
- Correct Bar Width on each chart. Replace any infinity symbol or implausibly large value with the intended finite width. If you are still in a comma-decimal locale without the localization fix, use a whole number. Confirm: the property editor shows exactly the value you entered.
-
Fix the source. Remove or guard any Bar Width binding that can divide by zero or grow without bound. If drift was confirmed, move the Designer to a
.-decimal locale or upgrade to a release with the localization fix. Confirm: the drift measurement shows a stable value across five Design/Preview cycles. - Re-add lost work. If you restored an older copy, rebuild the missing edits, including the pie chart. Save after each logical block rather than at the end of the session. Confirm: each save completes without console errors.
-
Save and fully reload. Save the project, close the report, close and relaunch the Designer, reopen the project, and open the report's Design panel. Confirm: the canvas renders, and the console shows
loadProject complete.with noClassCastExceptionafter it. -
Exercise the tabs. Switch between the report editor tabs several times, including Preview and back to Design. Confirm: no
Unable to commit changes made to ...ReportResourceerror and no NullPointerException fromDesignerPanel. - Re-read Bar Width. After the tab cycling, select each XY chart and compare Bar Width with the value you set in step 4. Confirm: every value is unchanged.
- Take a known-good export. Export the project now that it has passed steps 7 through 9, and label it as the verified baseline. Confirm: import the export into a scratch project, open the report's Design panel, and see the canvas render with a clean console and every Bar Width at its set value.
FAQ
Why does my Ignition report throw a NullPointerException after adding a chart?
The NullPointerException in DesignerPanel.commitChanges and onDeactivate is secondary. The real failure is the earlier ClassCastException: Error trying to coerce 'Infinity' to a number. in AbstractXYChart.fromXML. That exception stops the design editor from being created, and every later tab action dereferences the missing editor.
Why does Bar Width show the infinity symbol in the Ignition report designer?
The value went past the maximum a Java double can hold, about 1.8 × 10308. This happens when you type a very long digit string, when a binding divides by zero, or when the value drifts across preview cycles. The editor accepts it and saves the literal Infinity, which builds without the fix cannot load.
Why does Bar Width keep growing when I switch to preview with a comma decimal locale?
The value is written with the , decimal convention and read back by a parser that treats the comma as a grouping separator, so it grows by orders of magnitude each Design/Preview cycle until it overflows to infinity. Run the Designer under a .-decimal locale or use whole-number widths until you are on a release with the localization fix. Then confirm the value stays constant over five cycles.
How do I recover an Ignition report that fails to load with the Infinity coerce error?
Export the broken project first. Then restore a project revision or export saved before Bar Width went infinite, or open the broken project on a test gateway running a Reporting build that includes the Infinity fix. Correct Bar Width on every XY chart, save, relaunch the Designer, and confirm the Design panel opens with no ClassCastException in the console.