The barcode display on your HMI looks right while parts flow, then turns into a red error box the moment the line idles. The tag behind it is null between parts, the display component cannot lay out a null string, and a visibility script that reads the component's own code property cannot stop the crash. The fix is to guard the value before it reaches the component: put the tag on a custom property of the root container through a coalesce() expression that swaps null for an empty string, bind the component's text to that guarded value, and drive its visible property from the same string. The change is pure binding work, takes minutes, and fits any screen where a fixed code reader or handheld scanner writes a tag that sits empty between parts.
Why the display goes red between parts
The tag path that carries the decode — {[default]Station30/Barcode} in the examples below — is written only when the reader returns a code. Between parts it holds null (never written, or the tag quality has dropped) or an empty string written by a clear step. Because the display component is bound straight to that tag, the null lands on its code property. The component recalculates the rendered barcode geometry from that string, and a null string has no geometry: the client console fills with an exception raised inside the component, and the failed redraw leaves the red error state on screen.
Vision.Barcode - Caught unexpected exception while recalculating barcode size for string 'null'
java.lang.NullPointerException
The visibility script cannot prevent this, for two reasons. It runs on the component after the code property has already changed, so the failed recalculation and the red state happen first and the script only hides the aftermath; the next part repeats the sequence. It also merges three different states into one test — null, the empty string, and the string "0", which is a legitimate decode, not a no-read.
What the unguarded screen costs
Put numbers on it with illustrative inputs: a 5 s takt (12 parts/min), a PLC that clears the string tag 300 ms after each good read, and a 7.5 h shift. The clear leaves the component in its error state until the next decode arrives 4.7 s later.
With the guard in place, the same 4.7 s gap renders as a hidden control, and the value shows only during the 300 ms hold. Substitute your own takt and clear delay — the duty share scales linearly with both.
What you need
- An HMI or SCADA client whose components accept expression bindings and provide coalesce(), a function that returns its first non-null argument.
- Edit rights on the screen: you will add one custom property to the root container and change three bindings.
- The tag path that carries the decoded string, such as
{[default]Station30/Barcode}. - The barcode component's code property (the one currently bound to the tag) and its visible property.
The barcode display component may not expose custom properties of its own; many display components do not. The container does, and every component on the screen can read a container property, so the guard lives one level up. Plain labels bound to the same tag need the same treatment — the guide on hiding empty tag values in HMI label bindings covers those variants.
Guard the tag on the root container (steps 1-2)
- Select the root container and add a custom property to it. Name it BarcodeGuarded; the name is yours to choose, so keep it identical on every screen.
- Give BarcodeGuarded an expression binding:
coalesce({[default]Station30/Barcode}, "")
coalesce() passes the tag value through whenever the tag holds data and substitutes "" when it is null. If your platform signals bad tag quality as something other than null, fold that branch into the same expression so no non-string state survives the guard.
Bind the display and its visibility to the guarded value (steps 3-5)
- Rebind the component's code property from the raw tag to the guarded container property,
{Root Container.BarcodeGuarded}. The component now receives a string in every state: the decoded value or "". - Bind the component's visible property to a comparison on the same guarded string:
{Root Container.BarcodeGuarded} != ""
An empty string hides the component; any decode shows it. No script is involved. 5. Delete the property change script. If you still want side effects — a log line, an audit entry — trigger them from BarcodeGuarded, never from the component's raw code property.
Verify all four states
Force each state by hand before the line runs:
- Decode: scan a part. The component renders the barcode and stays visible.
- Cleared: write "" to the tag. The component hides and no new log entries appear.
- Null: idle the line or take the PLC offline. The component stays hidden and the recalculation exception stops appearing in the client console.
- The string "0": write "0" to the tag. The component must render a barcode — the old script would have hidden it.
Leave the screen up for a full shift and search the console for the logger that printed the old exception; the count should stay at zero. The same null-at-idle discipline appears in application code too — the article on a scanner's ignored first scan caused by a null previousValue is the app-side twin of this fix.
Common mistakes
- Guarding visibility but not the value. A "not empty" test on visible while the code property still reads the raw tag leaves the recalculation crash in place. Guard the string the component consumes.
- Inventing sentinels. Any string reserved as "no read" — "0", "0000" — collides with a real payload sooner or later. Filter null and the empty string only.
- Clearing before the compare. At a verification station, compare and count first, clear after the done bit; the ladder example in the barcode compare and count article shows the order.
- Leaving stale bytes behind. If the tag is fed from a receive buffer, clear it the way the PLC memory storage article shows, or the guard hides the display while the buffer still holds the old frame.
- Reusing the property change pattern on the payload itself. The property change payload fix trips over the same order of operations: validate the guarded value, not the raw event source.
Choose a reader whose idle output you can predict
The guard fixes the screen; the source gets cleaner when the reader's output behavior is explicit. Set a line-mounted reader to send on each read, then decide deliberately whether the PLC clears the tag after the done bit or holds the last value for the operator — the guard handles null, cleared and held states alike. Units such as the MV-ID813M-05S-WBN-SR integrate their white light, so a compact station needs no separate illuminator. Readers that push each decode as a string over Ethernet:
- Interface
- Fast Ethernet
- Resolution
- Up to 3 MP
- Interface
- Fast Ethernet
- Resolution
- 5 MP
- Interface
- GigE
- Resolution
- Up to 3 MP
Manual stations take their scans from a handheld reader over USB or Ethernet, and the display-side wiring is identical; the handheld code readers list wired and wireless units, and the suffix setup that commits each scan in your HMI is covered in the CR LF suffix article. For a fixed bench position, a compact USB unit keeps the desk clear: the LS-CRD-0047 is a 1.2 MP reader with a USB 2.0 interface and a 60-120 mm reading distance.
- Resolution
- Up to 3 MP
- Shutter
- Global
- Interface
- USB
The decision, per case
- Red error box between parts: apply the five steps above. The guard removes both the error state and the log spam.
- Screen looks fine but the console fills: same guard. The crash sits in the recalculation path whether or not a script masks the visual.
- Operator needs the last code during the gap: skip the PLC clear and keep the guard for the null case at startup.
- New station: choose the reader by interface and reading distance first, then wire the tag through a guarded container property once.
Shortlist hardware in the fixed code readers category or the camera and code reader finder.
The configurator matches a camera, lens, light, light controller and cables to each other, step by step, and lists only parts that fit what you already picked.
If you send us your tag path and reader model through the contact page, we will check the output mode and the guard expression with you before you order.
Questions
Is the NullPointerException a bug in my project or in the display component?
In the component. It rebuilds the barcode image geometry from its code property, and a null string breaks that internal call no matter what your scripts do, so the same log line appears on every no-read window. Report it to the HMI vendor's support with your screen as a replication case, and ship the coalesce guard now — it removes the trigger instead of waiting for a patched component.
Does coalesce() also convert an empty string to something else?
No. Coalesce replaces null only. A tag cleared to the empty string passes through unchanged, the component receives a string it can lay out without error, and the visibility expression hides the display because the guarded value equals the empty string. Null and cleared therefore end in the same place: a hidden, quiet component with no exception in the log.
Should the PLC clear the barcode tag after each part?
Clear it when the value must not survive to the next part, for example at a match-verification station that compares every scan against a recipe. Hold it when the operator needs the last code visible during the gap. Both work with this guard, because the expression handles null, empty and held values the same way — the display shows real decodes and hides everything else.
Which fixed code readers send decoded strings to an HMI over Ethernet?
Readers in the fixed code readers category with a Fast Ethernet or GigE interface, such as the MV-ID3013PM-12M-WBN, push each decode to the PLC or gateway your tag reads from. Match the reader's interface to the PLC side, and set the output to send on each read so the tag state between parts is deliberate rather than accidental.



