What's New in Flow 7.2.0
A large CLI expansion, full OAuth 2.0 for REST sources, SQL connection security, chart authoring automation, event scheme Skip To, and one hundred and twenty tracked correctness fixes across the engine, templates, charts and the configuration tool.
Flow 7.2.0 is a feature release. Its headline areas are the Config CLI, which becomes capable enough to build and audit an entire model unattended, the Web Service data source, which gains a complete OAuth 2.0 implementation, SQL connection security, which brings encryption and certificate validation to every connection Infohub makes to its own database, and Skip To on event schemes, which lets a scheme stranded behind a data gap resume.
Behind those sit one hundred and twenty tracked work items — the great majority of them correctness fixes in the engine, integration, templates, charts and the configuration tool. This page covers all of them. Where a fix is subtle, it says what went wrong, because that is usually what tells you whether you were affected.
Automation: the Config CLI#
The largest single area of change. The command line surface — now 506 options — is broad enough that Infohub's own demonstration and QA models, 25 industry models, are built entirely by script with no interface interaction. A handful of verbs are recognised but not yet available: each says so by name and exits without changing anything, and they are planned for a future release (see Deprecations and Breaking Changes).
Import from the command line. --import takes --import-type model, templates, toolbox or full, with --import-destination-id to choose where a model subtree lands and --conflict-handling Skip|Overwrite|Rename for toolbox items — functions, enumerations, attributes and calendars — that already exist. Every import type runs as a deep import on 7.2.0.
Local templates. --instantiate and derivation work from templates in the same database, not only from a template server; --update-from-template follows an entity's link back to a local template; out-of-sync detection covers local templates for folders, metrics, event schemes and measures; and instantiating from an unreleased local template warns up front instead of silently doing nothing.
Change logs. --logs lists an instance's change logs for a period — --duration (for example 12h, 3d, 2w) or --start-time/--end-time — filtered by --log-type (System, Measure, Metric, Chart, Connection, Dashboard, Engine, EventScheme, and so on) and --log-level (Information, Warning, Error), in table, CSV or JSON form. It answers "what changed in this model last night" without opening the interface.
Housekeeping. --clear-unused-modules removes plugin packages no connection uses, which was previously only available from the Packages window.
Skip To. --gap-skip-to with --gap-skip-to-date moves an event scheme's processing position forward past a data gap, the same command the Event Scheme form offers. It refuses a template scheme, a date at or before the scheme's current position, and a date in the future, and writes nothing in those cases. See Events, calendars and time schemes below for what the engine does with it.
Chart authoring. Charts can now be created and configured from the CLI through their real factories, so a scripted chart is constructed exactly as a chart built in Flow Config is. --create-chart takes a named --chart-constructor, property setters are validated through the framework rather than written blindly, and --list-chart-node-options tells you which components will accept a given measure, metric, or event scheme. --list-chart-tree prints the resulting structure so a script can assert on what it built.
Chart templates. Charts can be released and un-released as templates from the CLI.
Template servers and federation. New verbs cover the setup that previously required the interface: --create-template-server (writing the full property set, with the server key and any proxy password stored encrypted), --create-server-token, and --register-with-bootstrap.
Reliability. A batch of work went into making the CLI trustworthy in a script:
- Exit codes are honest.
--createpreviously logged a real failure and then reported success and exited 0 — which matters because a partly-created database has a fraction of its tables, and any script trusting the exit code carried on against it. Failure is now exit 10. - The batch wrappers no longer swallow the exit code.
infohub-config.batandihc.batended with a cosmeticecho., and a batch file exits with the code of its last command — so the wrapper reported success for every failed command, however the CLI itself had exited. Anything gating on the exit code saw green. Fixed. - Logging is reliable. Parse errors, edition-gated verbs, and
--helpall write to--log-filenow; a single shared writer replaced two writers corrupting one file; and progress indicators go static when output is redirected. - Gated verbs name themselves with a specific "not available in Flow 7.2.0" message instead of a generic error indistinguishable from a typo.
- A bad invocation no longer launches the interface — it exits 1.
- Tab completion is derived from the parser's own option set, so what it offers is what the parser accepts.
--list-connection-typesno longer loads plugin package blobs, taking it from minutes to seconds on an instance with large packages.- Entity type names are matched case-insensitively on both sides of an instantiation.
--destination-entity-type metricfolderwas previously rejected whileMetricFolderwas accepted, and the error listed the valid types in their canonical casing without saying that the casing was what it objected to.
Correctness in create paths. Template-ness now follows the parent on every create path, including both bulk creates — a bulk create inside a template previously produced ordinary model measures, invisible to instantiation and with no version bump to announce it. Created measures also take max(sibling) + 1 for display order, so a scripted model reads in the order it was built.
Instantiation. --instantiate no longer fails on a template containing an event-sliced measure. Three separate lookups assumed every component of the source model had a mapping in the destination; any one of them could abort the merge with a key error, leaving nothing created. Related: an instantiation whose source is not a released template now fails as a precondition instead of reporting success having created nothing, and a CLI function rename applies the same name rule the interface applies.
Template updates from the command line. A metric-level --update-from-template could attach the updated measures to the wrong metric -- a foreign-key failure where the mistaken id matched no metric, and a silent mis-attachment where it matched one. The folder-level update was unaffected, and only by accident. Eight related defects in the same area went with it: template-server loads that failed after a successful fetch, entry points that reported "refresh first" however often you refreshed, --create-template refusing every promotion, --recursive accepted and then ignored, --cleanup-delinked failing on any instance that actually had rows to clean, --attach-measure-time-scheme failing when re-attaching, and a result that reported success alongside its own failure message.
Templating verbs behave like the interface. A later pass, driven by a battery that runs the same template operations through the interface and the CLI and compares the shapes they produce, closed the remaining differences:
--instantiatebinds a measure's event context in place — to the event this instantiation creates, else the candidate in the destination folder, then the nearest ancestor, then the only candidate — instead of the first same-named model event anywhere in the model. Several candidates with none in place is an error that names them and points at--mapping-file.--update-all-out-of-syncnow scans template-linked folders, metrics, event schemes and measures rather than templated folders only, and a failed single-entity update carries the reason it was refused instead of a bare id.--update-from-templateand--list-out-of-syncacceptfolderandeventas entity types like the other verbs do.--delete-entitydeletes with the interface's cascade: folders to any depth, their metrics and event schemes, and every measure beneath, in one transaction. It previously stopped on the first child table without a database cascade, so a folder holding an event scheme with refresh triggers, or a measure some calculation depended on, could not be deleted at all.- Instantiating or deriving a single measure binds its parent and calculation dependencies to the copies in the destination, or refuses before creating anything. It previously left them pointing at the template's own measures, so the template gained model children and the next instantiate failed on a duplicate key.
- A folder derived into a template folder creates its event schemes too, and template-folder destinations resolve their folder.
--cleanup-delinked --property-type timeschemeremoves the measure's limits on that calendar as the interface does, and refuses while a consumer, tag transform, sourced limit or message segment still uses it. Dependency auto-mapping picks only from the candidates the interface's mapping dialog would offer — it had bound a template to a same-named model event scheme — and a template operation asks for the mapping once rather than re-showing the dialog after you close it.--attach-measure-event-schemewrites the event scheme sets the interface writes, one per calendar refresh, plus the time slice aggregation property; without them the Data Engine failed on every scan while the CLI had reported success. It refuses a foreign event on a measure that aggregates an event, clears the measure's time slices so the engine rebuilds them, rolls the link back if the sets cannot be written, and re-attaching an already-linked event repairs the sets instead of adding a duplicate row.--attach-measure-consumerstamps the default Integration Engine and the measure's calendar or event scheme, as a drag in the interface does; a binding written without them was never sent and never appeared on the Integration tab. A measure on several calendars or event schemes must say which with--time-scheme-idor--event-scheme-id, and an instance with no Integration Engine is refused rather than given a row that can never send.--register-with-bootstrapreports a registration that Flow Bootstrap refused, with Bootstrap's own reason, instead of printing success and exiting 0 while the instance silently never ran.
Placement rules now match the interface. --create-metric-folder and --create-template-folder checked only that the parent existed, not that it was allowed to hold the child, so a script could build folder trees the interface refuses and --move-folder would later reject.
New read and edit verbs, each closing a gap where something could be created but never listed or changed afterwards: --list-measure-limits, --list-event-attributes, --list-dashboard-panels, --update-dashboard-panel, --delete-dashboard-panel, --update-chart-item-event-attribute, --attach-event-trigger-time-scheme and --attach-event-trigger-event-scheme. The last three matter beyond convenience: without them a scripted chart could be given a measure but nothing to break it down by, and so rendered empty, and an event trigger could not be given a calendar or another event scheme as its source at all -- and a trigger with no source never fires.
See Automation & the Config CLI.
Capturing CLI output. Shell redirection (> out.txt) from a Command Prompt produces an empty file. The CLI is a GUI-subsystem executable that borrows the caller's console, so its output goes to that console rather than to your redirect. This is long-standing behaviour and is not new in 7.2.0. Use --log-file, which captures reliably from every invocation path. Interactive use is unaffected — the text appears on screen normally.
Web Service data source: OAuth 2.0#
REST sources gain a full OAuth 2.0 implementation.
Client authentication methods: Client Secret Post, Client Secret Basic, Private Key JWT, and None. Private Key JWT is what enterprise identity providers increasingly require, and it is now supported directly.
Grant types: Client Credentials, Authorization Code, Refresh Token, and jwt-bearer.
Assertion handling. Security algorithms default to RS256, a fresh jti is minted per assertion unless pinned through the Claims property, and sub defaults to the client id — the values most providers expect, without having to supply them.
Token handling. Tokens are cached per configuration, renewed with an expiry margin rather than after a request has already failed, and refreshed per request through a delegating handler. A token revoked by the provider before its stated expiry is now detected from the rejected request, discarded, and reacquired — so a mid-shift credential rotation on the provider side heals itself.
Validate Server Certificate is a new property. It defaults to False so development against self-signed endpoints works out of the box; enable it for anything reaching a real service.
Response handling. Response shape handling was extracted into a dedicated parser with regression tests, and gained two capabilities: parallel timestamp and value lists (common in weather and forecasting APIs) alongside the usual array of objects, and Unix timestamps in seconds as well as milliseconds.
Header validation. The Headers template is validated when the connection is tested, so a malformed header line is reported then rather than surfacing later as an unexplained authorisation failure.
Response caching is bounded by both a duration and an entry cap.
See Web Service Data Sources and OAuth 2.0 for Web Service Sources.
Security and licensing#
SQL connection security. Infohub's own connections to its database gain explicit encryption control: a connection security mode, Trust Server Certificate, and Host Name in Certificate. The settings are honoured by the configuration tool, the CLI and the services, so an instance can be brought in line with a policy that requires encrypted SQL traffic. The CLI exposes them on every verb that opens a connection, including the instance-management verbs — --version, --migrate, --import, --backup and --license — which previously ignored them and connected with encryption optional however they were invoked. --migrate being in that set was the operational problem.
A malformed licence key can no longer be saved. A key that failed to parse was written to the database anyway, after which the configuration tool could not open the instance to correct it — the tool needed the licence to start, and the licence it had was the broken one. Keys are now validated before they are stored.
Credentials set from the command line are stored encrypted. --set-system-property and --set-connection-property wrote their value straight through, so setting a password from a script stored it as plaintext. Every component decrypts these values when it reads them, so the stored plaintext was then put through a decrypt and failed -- for the instance password that presented as a Data Engine which started, reported itself healthy, and retrieved nothing at all. Values on properties the product marks as hidden are now encrypted on write, matching what the interface has always done. If you set a password with either verb on an earlier build, set it again on this one.
An unlimited licence is now truly unlimited. Counts were still enforced against a limit that an unlimited licence should not have had.
Backfill clamp for FLD and V2 licences using a GUID. The engine computed a backfill cutoff from a licence creation date that a GUID-keyed licence does not carry, producing a cutoff in year one. The cutoff is now computed only where it applies, and only from a real creation date.
The instance Server no longer serves a stale certificate. On Windows the instance Server takes its certificate from the machine's HTTP.sys SSL binding for its port. When that binding already existed at startup — left behind by a reboot, a crash or a forced stop — the Server took it as correct and never started the poll that would have learnt a rotated thumbprint from Flow Bootstrap. After a certificate rotation the Bootstrap port served the new certificate while the Server port kept the old one, and once the old one expired every proxied request returned HTTP 502; restarting the service and rebooting did not help. The Server now reads the thumbprint actually bound to its port, rebinds only on a mismatch (so a binding an administrator manages deliberately is left alone), always runs the refresh poll, and logs a warning rather than failing to start when it lacks the privilege to rebind.
Engine and data correctness#
The Data Engine no longer crash-loops on a non-English Windows install. On a brand-new installation where every component deployed normally, the engine could die immediately and repeatedly, before writing a single log line. Its assembly resolver walked the installation folder asking every file whether it was an assembly; on a malformed file that question throws, and composing the error message needed a framework text string, which under a non-English language went looking for a translation that does not exist -- which asked the resolver to find an assembly, which started the walk again. It appeared only on non-English systems, because under US English the framework answers that lookup without asking anyone, which is why it reached customers rather than showing up in testing. Two sites hit it. The resolver now answers translation requests directly, refuses to re-enter itself, and only examines files that could actually be assemblies.
Open-ended retired events. A retired event period could remain open-ended, which left durations growing without limit and every duration-derived measure above them wrong. Retirement now always closes the period. Separately, the engine no longer leaves event periods both unpreferred and open-ended.
Deadlock on queue-pending promotion. Concurrent engine workers promoting queued measures could deadlock against each other on the measure time-period pages. The promotion path is hardened and the transaction owners retry on deadlock, so a scan recovers instead of faulting the measure.
Deadlock victims on tag-sourced measures are retried, not quarantined. When a tag-sourced measure's value write was chosen as a SQL deadlock victim, the exception was rewrapped on its way out, so the retry wrapper that already handles deadlocks on other retrieval paths never saw it. The measure was quarantined for five minutes instead, and if the retry deadlocked again the back-off went to thirty minutes, an hour, then never — an edit or an engine restart was needed. Typical trigger: concurrent backfills after a bulk instantiate and deploy. The deadlock is now rethrown ahead of the quarantine and retried immediately on a fresh context.
A measure with two tag transform configurations is named. Such a measure made every full-model load — instantiation, copy and paste, template update, export — fail with a bare "An item with the same key has already been added", which named neither the measure nor the cause. The loader now reports the measure, its metric and the transform ids. The fix is diagnostic: healthy databases load exactly as before.
Calculated measures stuck in processing. A calculated measure whose dependents never had QueuePending cleared would sit in processing indefinitely.
Time slice completion. The engine no longer moves forward while time slice processing is incomplete.
Measure time slice coverage. Time slices did not always cover the whole time period for Manual and Set-To-Previous measures, leaving gaps that read as missing data.
Split and backfill. Splitting a measure now sets backfill so the time slices are re-created, and editing or splitting an open-ended event correctly ends the unpreferred event.
Aggregated source changes. Changing an aggregated measure's source from an event to a measure now clears the event-related configuration that no longer applies.
Purge during a backfill. Measure processing could get stuck if a purge ran while an event scheme backfill was in progress.
Tag dependency cycles. Dependency walks are now cycle-safe, cycles are reported rather than causing a crash, and stranded tag transform configuration left behind by a retrieval-type change is cleaned up. The cleanup runs once, during the upgrade, and writes an audit trail of what it removed.
Measure collections. Engine scan and execution defects in measure collections are fixed, along with the unhelpful error the engine raised while processing them.
Calculation start. "Beginning of time" is now available as the first calculation datetime, for measures and for calculated event attributes.
Calculation boundary timestamps. A calculation instance's own date is used as the boundary value timestamp.
Quality handling. Null values are guarded when integrating raw data outward, and a null PeriodEndQuality no longer causes a failure.
Stale calculation cache. A change to a calculation's dependencies could leave a stale cached assembly indexing a dependency that no longer existed, producing an index-out-of-bounds error when the measure was previewed. Fixed.
Events, calendars and time schemes#
Skip To. An event scheme whose trigger data has a gap wider than its trigger query window never moves forward: every query returns nothing, and the scheme sits at the same position indefinitely. The Event Scheme form now offers Skip To when an active scheme is more than 21 days behind. At the top of its next cycle the Data Engine closes every open preferred period that started before the current position, moves the scheme's position to the date you chose, re-pends the event-fed measures and time slices from the earliest closed period, and clears the command. A period that starts at or after the position — a manually started event — is left open. The same command exists in the CLI (above). Alongside it, the event trigger query window on the Ignition, InfluxDB, OPC HDA, OPC UA, Wonderware and Wonderware 2017 historians goes from 7 to 21 days, matching Canary, so a backfill crosses history three weeks at a time and a gap of up to three weeks no longer needs intervention at all. See Event Lifecycle Operations.
Refresh triggers link directly to a data source. A refresh trigger on a measure calendar or an event trigger was previously reached through the measure's or trigger's own retrieval connection, so a trigger whose source was a calculated tag — or any tag whose data source could not report modified data — could not carry one, was not created on import, and was not instantiated from a template. Refresh triggers now carry their own connection: any retrieved measure or retrieved event trigger can take one, and you give it its data source by dropping a source that can check for modified data onto the refresh trigger node. The upgrade script carries the trigger links across. Models that import or instantiate refresh triggers on calculated tags now get them.
Replicated weekly periods are matched on start time as well as week and year. On a calendar whose year does not start in January, the week number is a calendar week while the year is the financial year, so two weeks a year apart can share the same label. A replicated weekly measure posting into such a calendar matched both and failed with "Couldn't map the time period ids", for both weeks, every time. The match now also requires the local period start to be within 14 days of the posted one, which separates the two and still tolerates sites whose week boundaries differ by hours or a day. Stored labels and the engine are unchanged, so the tiers can be upgraded in either order.
- Shift schemes can no longer be configured such that consecutive shifts leave a gap in the time periods between them.
- Time period / time scheme configuration is fixed for week, month and quarter schemes, including the month-offset case.
- Manual calendars are now taken into account when report periods are determined.
- Event timelines start the time axis at the period start rather than snapping to the first event, so an empty run-in is visible rather than hidden.
- Refresh triggers ignore null datetimes and log a warning instead of failing.
- A new refresh offset can be added to a measure again — selecting a calendar node had made the command unreachable.
- Orphaned
EventTriggerRefreshTriggerrows left behind by an event-scheme or template delete are cleaned up. EventPeriodProxygains a Username property.
Integration#
Measure integration missed attribute-only changes. This is the most consequential integration fix in the release. An attribute edited on an event period that had already ended was stamped with the period end, so it was born below the integration's watermark and could never be selected unless the measure value happened to change as well — the change was simply never pushed. Detection and sending now both key on the attribute's modification time rather than its business time. The upgrade script clamps watermarks that the old behaviour had already advanced into the future.
Placeholder time zones. [periodstart] and [periodend] in a measure integration resolved against the server's operating system time zone rather than the instance time zone, so a server in a different zone from the plant produced shifted timestamps.
Event integration issues are fixed, and EventSchemeConsumer.DateTime is no longer reset to the minimum date during a backfill.
Raw data push no longer throws when a measure has no connection properties.
Only consumers that can take raw values can be attached to a tag. The Integration panel accepted any consumer dropped onto a timestamp measure, because a cached plugin type was returned without checking it was the right kind. A consumer that cannot push raw values — the Azure Event Hub and MQTT consumers, for instance — produced a binding that could not be deployed and failed at the Consumer Host with "does not implement the ICanPushRawValues interface". The drop is now refused for timestamp measures only; ordinary measures accept every consumer as before, and the CLI applies the same rule.
Endpoint messaging on the measure value update endpoint now distinguishes an error updating the value from an error updating the value exception.
Data sources and consumers#
- MySQL data source and namespace connections gained a Port property.
- Ignition data sources support Timescale.
- Ignition datetime tags now return their values. A tag with Type
3(datetime) came back empty for every timestamp, because the data source read Ignition'sstringvaluecolumn, which Ignition leaves empty for date tags, instead ofdatevalue. On SQL Server, a datetime event attribute failed outright instead. Datetime tags now readdatevalueon SQL Server, MySQL and PostgreSQL and return it as text in the formyyyy-MM-dd HH:mm:ss, with fractional seconds added only when the stored value has them. If you had worked around this by copying dates intostringvalue, that is no longer needed. - Canary V24 now returns numeric values stored as a string data type, and can get an attribute value on a timestamp matching an event trigger.
- A Canary custom-expression memory leak on an incorrect tag reference is fixed.
- Model attribute syntax is supported in attribute enumeration queries, and a lookup enumeration query no longer stops at the first failed ordinal — one bad lookup previously blanked every later ordinal in the same job.
- SparkplugB consumer properties are all visible in the window.
- The MQTT consumer supports a
[Version]placeholder in custom topic and payload formats, and its model attribute placeholder replacement is no longer case-sensitive. - Azure Event Hub consumer enhancements, including fixes to unreachable Unix time placeholders and an open-period crash risk.
- The SQL consumers now offer a valid example query. The example produced when you pick a table and column in the namespace browser was assembled from fragments that ran together, giving statements no engine would accept -- one customer reported
syntax error at or near "beginupdate", which Infohub itself had generated. None of the four SQL consumers had produced a usable example on any table. Each now emits a single valid statement in its own dialect, built from the real schema, table and column, and written so that re-sending a period updates the existing row instead of duplicating it or failing. Note this fixes the example that is offered: a query already saved on an existing consumer is left untouched, and is best replaced by re-picking the table and column. - Connection strings may now contain quotes and semicolons.
- Windows-host data sources no longer fail with "Pipe is broken". The shared host process and pipe lifecycle, not the vendor SDK, was the cause.
Templates#
- User-added calculations are preserved on a locked-retrieval template update, rather than being removed.
- A
- Copysuffix is no longer appended to measure and event descriptions when instantiating more than one copy of a template. - A model import no longer drops a measure calendar's template link, which previously caused the next template update to add a duplicate calendar.
- Event scheme set instantiation no longer duplicates event scheme sets.
- Updating a measure that carries event attribute context no longer fails with a key-not-found error. The metric and event-attribute id maps were not seeded before the update read them.
- A template update no longer overwrites a measure's Time Slice Aggregation. The aggregation type that recombines a measure's event-context time slices into the event value defaults to Sum and is never derived from the retrieval aggregation, so a measure retrieving a time-weighted average has to be switched to Average by hand — and every template update reverted it, because the template's value was pushed regardless of locks. It now has its own lock, beside the Event Scheme Aggregation dropdown on the measure form's Time Slice Aggregation tab: first instantiation writes the template's value as before; an update writes it only when the lock is set; otherwise the instance keeps its own. Existing templates default to unlocked, which leaves instance values alone. The lock is visible on the form (an earlier build hid it at load), it takes the panel's own background like the other locks, and a template that locks the context no longer greys out the aggregation dropdown on an instance — the context lock protects the calendars, event contexts, refresh offsets and triggers, not this property.
- A template update no longer bumps the version of a measure with limits that did not change. Any measure carrying limits was sent down the full rewrite path on every update, taking Version+1 each time, so all of its instances and derived templates showed "update required" immediately afterwards — on a template-server estate the indicator never settled, and every spurious update was another slow one. The limit re-sync stays; the version is bumped only when that re-sync actually changes something. Two comparisons that always reported a difference (a limit value against the template's raw XML, and a source id compared unmapped) are corrected with it.
- Recursive Update is much faster, and a folder update no longer aborts on its second pass. A Recursive Update on a template-view folder updated every template-linked entity whether or not it was behind its template, and rebuilt the entire model state from the database for each one. It now skips a metric, event scheme, folder or measure already at its template's version — the same rule the tree uses for the "update required" indicator — and reuses the run's model state, reloading only what a pass wrote. On a large template-server model a Recursive Update after a change to one base measure went from about 70 seconds to about 13 in the reporter's retest, and the CLI's
--update-instances-offrom about 28 seconds to 16 for 19 instances (and it now releases the entities it created, which it had detected but never put on the result). The same shared state was also why a model-side folder Update could fail with a duplicate key on the second instance of the same template metric, or on a measure's limits, calendars or consumers: the second pass could not see what the first had written. Every entity a pass writes is now reloaded before the next. - A renamed event scheme instance gets its engine. The second instantiation of a template folder or event that keeps the template's event name takes the "- Copy" rename path, which built the event scheme without an engine, so the insert failed and the whole instantiation reported "Something went wrong". The rename path now applies the same engine rule as a plain create.
- Template update performance — see the configuration tool section below.
Charts and visualization#
- Chart import no longer throws a key-not-found error when the dependency mapping scope was narrower than the import scope, nor when a dependant reclassification defeated the mapping gate.
- Re-importing a chart that already exists no longer fails with a duplicate-key error on
ChartComponentProperty. This was the wall immediately behind the mapping fix above: with the gate corrected, the import got far enough to write component properties and collided there instead, so a first import succeeded and every subsequent one failed. The cause was worse than the error suggested. Two sets of ids -- those from the file being imported and those already in the destination -- were being kept in one lookup, so an entry for one could shadow the other and two different components could resolve to the same one. Where a unique index caught that, you saw the duplicate-key failure; where no unique index covered it, property rows were written against the wrong component and the import reported success. The two sets are now kept apart, at both the component and the chart-item level. If you have imported charts into an instance that already held them, it is worth re-checking that those charts carry the properties you expect. - Copy and paste of event-based charts works where limits are used.
- Portrait tables gained a Visibility property, and the hidden-when-zero misalignment was fixed.
- Chart items whose image key rendered as a grey icon in light mode are now transparent.
- A tag with a string value shows it on a Widget. A tag retrieved from a text column had its string value dropped on the way into the Widget chart, so a text display stayed blank. The string value is carried through, and is shown whenever the tag has no numeric value.
- AnyChart upgraded to 8.14.1 with a new licence applied, and the version is pinned exactly rather than floating on a caret range.
- Dashboard loop cycle times now have a properties dialog.
- Event-based forms gained an
AllowAttributeEditpermission.
Configuration tool performance#
Template updates and startup were both meaningfully slow on large models. Several changes address it:
- The plugin type cache is guarded by package id, avoiding a package lazy-load on every cache hit.
- The connection type plugin cache is pre-warmed at startup, on a dedicated context to avoid a shared-context race.
- Model attribute synchronisation during a template operation is gated and scoped to the updated subtree rather than the whole model.
- Post-template-operation refresh uses targeted queries instead of scanning tracked entities.
- Release and un-release stamping is batched, with set-based parent version bumps.
- Deployed data source and consumer namespace refresh is faster — the proxy type was being rebuilt on every call — and data source item tree nodes are batched during lazy-load refresh.
- Namespace loading for lazy-loaded items is faster.
- Image resources are preloaded, improving startup time.
User-defined functions#
Two related fixes that together close a corruption path:
- Renaming a function no longer shows and re-saves the old declaration.
- Unnamed functions are refused on both create and rename. An empty name previously produced a pattern that could rewrite function bodies and calculation expressions across the whole database.
Configuration tool interface#
- The Model view no longer loses metrics, and F5 no longer crashes the tool, after deleting a tag.
- A Model view node whose entity was deleted elsewhere — by the CLI, or by another Flow Config — is dropped by Refresh and no longer throws when right-clicked.
- The Message view status is re-evaluated after you edit a message. Adding a notification server to a message definition left the "no notification servers configured" warning on the tree node until Flow Config was restarted, because the node's status was computed from collections loaded when it was first drawn. The same applied to trigger and section faults, and a trigger deleted in the message form stayed attached to the tree, so a later deploy from the tree stamped a row that no longer existed. After each save the definition, its notification servers, triggers and sections are re-synced and the node and its channel re-evaluated; deploying from the tree also updates the Deploy/Undeploy button on an open message form.
- Deleting an event refresh trigger from either node removes the pair. A configured refresh trigger is drawn as a "Refresh Trigger" node with a connection-name child. Deleting from the child removed the trigger but left the parent node, which the tree then selected and failed on.
- The status bar no longer reads "Ready" while the connect refresh is still running. The startup preload finished first and wrote "Ready" with the wait cursor still showing; it now leaves "Ready" to the refresh itself.
- The Deployment view no longer stalls startup on an unreachable platform, and no longer blanks the components on a slow one. Each platform probe is bounded — a platform that does not answer within the cap shows the usual Bootstrap fault with "(no response within ... seconds)" — and the version and running items are read from a single request, so a slow first answer no longer cancels the second and paints every engine, server, data source and consumer on a healthy platform red. One stopped Bootstrap previously held the model tree back by about 45 seconds.
- A deploy that Flow Bootstrap refuses is reported as refused. Both the Deployment view and
--register-with-bootstrapposted the registration and discarded the response, so a refusal — bad credentials, an unreachable instance database — was shown as a successful deploy while the instance silently never ran. The refusal is now reported with Bootstrap's own reason. Bootstrap itself no longer answers success for a database that carries no instance id, which was the one refusal the callers could not have seen. When the refusal was a login failure for a Windows account, the message adds the fix: the interface sends the SQL login from SYSTEM > Properties, falling back to Windows authentication when it is empty, so enter the SQL login there and deploy again. A database upgrade's per-platform re-registration shows the same reason instead of discarding it. - A derived function shows its real validation status and can be validated. A function derived from a template server always showed the green validated icon and, with the button no longer disabled, clicking it compiled and saved a read-only function. The icon now reflects the function's status, only the definition text is read-only, and Validate still works. A measure calculation edited after selecting a dependency node is tracked again — such an edit neither reset the icon nor saved.
- The calculation context menu is built for the selected node rather than the node under the mouse, so a menu opened from the keyboard offers the right commands, and New Measure Collection is kept off a calculation that has dependencies — it overwrites the expression and saves immediately, with no confirmation.
- The event-context menu works on a deployed measure. Right-clicking an event context or calendar on an active measure did nothing, so "Show in Model/Template" needed the measure undeployed first. The menu stays attached and each command is gated individually; Delete is shown again on event-context nodes, enabled when the measure is not active and otherwise greyed with the reason.
- A second enumeration group window no longer opens when one is already open for the same group.
- Drilling through on pending measure event periods in the Monitor is fixed.
- FormDiagnostic reads "No Value" where no data exists, instead of back-extrapolating a first value into a range that has none.
- The Validate icon carries more significance, and it is now visible when an expression has not been validated.
- A duplicate chevron painted in the manual retrieval panel is fixed.
- Deployed metrics and events can be moved between engines without a forced manual undeploy first.
- The Deployment view refreshes after a model import, and an import that left data sources and consumers with no platform now assigns the default one.
- Exporting no longer fails with "Collection was modified" when the collection changes between the export form opening and the export running.
- Exception line reporting is fixed, and Event Viewer logs now reference the MeasureID as well as the MeasureCalculationID — the calculation id alone rarely identified the measure a reader was looking for.
- Tree node edit cancellation no longer removes the node when the user was accepting the default text, and nodes created with a default label are now saved.
- The Reports tree removes nodes created in error.
- Freeze configuration combo boxes on the time scheme form are fixed.
- The Toolbox view refresh problem is fixed.
- Refresh-on-connect is guarded against re-entrancy that could terminate the configuration tool.
- A read-only cell no longer enters edit mode on click.
Upgrade robustness#
- A failed pre-migration database backup is no longer silently swallowed. The configuration tool previously proceeded to load without upgrading the database.
- Database scripts are forced to CRLF, fixing a 7.2.0 upgrade that failed with "Incorrect syntax near 'go'" when scripts had been committed with LF endings.
- Index rebuild fragmentation limits are corrected for the different rebuild options.
- Update Script 7.2.0.sql carries data repairs for the event scheme set and retrieval-cleanup family, a time period month-offset repair, a null-quality repair, an integration watermark clamp, and an edit covering index. Release hygiene work makes the script set consistent and re-runnable.
Installation#
Convenience batch entry points for the CLI are installed, and .pack files are now included — which also fixes installed builds silently missing the icon pack and falling back to composing icons at runtime.
Quality assurance#
The release ships a CLI smoke, soak, and full-surface QA harness under tools/qa, along with 25 scripted industry demonstration models built CLI-only, an invariant pack of database oracles, a migration rehearsal, an MQTT placeholder fixture that loads the real consumer assembly, a stubbed template server, a resolver repro that forces a non-English culture, a consumer-SQL guard that executes every shipped example query against real PostgreSQL, MySQL and SQL Server engines, and a templating battery that drives the same template operations through the interface (by UI Automation) and the CLI and compares what each produced. These are the harnesses that found a large share of the silent-failure defects fixed above -- including several found during the close-out pass itself, after the tracked work was complete, which is why a few of the fixes listed on this page have no ticket number of their own.
Known issues#
These are open in 7.2.0 and tracked for a later release. None of them changes stored data except where noted.
Templates and configuration#
Instantiating a template straight after editing one of its measures can fail. Saving a change to a template measure that has child measures (for example a measure with rollups beneath it) marks that measure as unreleased while its children stay released. Instantiating the template folder in that state stops with The given key … was not present in the dictionary when you press Continue, or Import failed for instance 1 from the CLI. Nothing is created. Workaround: release the template folder (right-click › Release, or --release on the folder from the CLI) before instantiating or updating from it. Note that --release on a single child measure in the CLI does not release its parent measure; release the folder instead.
The form editor offers Add › Tab only while a form has no tabs. Workaround: drag a metric onto blank space in the Tabs tree to create further tabs.
Renaming a shift pattern to a later start time is not checked against the previous pattern. Creating a pattern is checked; renaming is not, so the previous pattern can end up finishing mid-shift. Workaround: after renaming, check that the previous pattern still ends where the renamed one starts.
Saving settings in Config while a CLI script is running can fail with a "file in use" error, after which the calendar form may show Value of 1/1/0001 is not valid. Workaround: do not save settings in Config while CLI scripts are running; reopen Config if it happens.
A non-numeric period in Dashboard Loop Properties shows a raw error dialog, and the diagnostic grid can show a final row past the end of the range with a negative duration. Both are cosmetic.
Automation#
A calculated event attribute created from the CLI without --expression never calculates. The default expression does not compile, and the engine skips the attribute with a logged error. Workaround: always pass --expression, and return a string — return "0";, not return 0.0;.
Events, messages and charts#
A derived event attribute can be typed into from an event form in the browser, which overwrites the derived value with a manual one. Workaround: do not type into derived attribute cells; only free-entry attributes are meant to be edited there.
After a 50:50 split of an event period whose length is an odd number of seconds, the two halves cannot be edited from the event form — the save is refused as overlapping the neighbouring period, because the split boundary falls on a half second.
A message placeholder with a format, such as [Value("0.00")], ignores the format and prints the raw value.
The chart data API returns an error for a period without a time zone. periodStart=2026-10-11T08:00:00 fails with HTTP 500. Workaround: always send a time zone — 2026-10-11T08:00:00Z or an explicit offset.
Integration#
A Flow-to-Flow consumer logs a warning on every push that a measure has at least one limit instance that is linked to another measure. The warning is harmless — such a limit is correctly not replicated — and only its repetition is the defect.
[Version] is not substituted on every MQTT publish path. It resolves in a measure value's custom topic and payload, but the event-scheme, attribute and raw-tag publish paths still publish the literal text [Version]. Workaround: do not rely on [Version] in the topic or payload formats of those three paths.
Installation and upgrade#
The first run of the installer can fail with error 1603 while Flow Bootstrap is running. See Upgrading to Flow 7.2.0: stop the Flow Bootstrap service, wait for it to report Stopped, then install, and run the installer again if 1603 still appears.
Upgrading a database still on Flow 5.3.x can stop partway through the 5.4.0 step on some older databases. The upgrade runs in a single transaction, so the database is left on its original version, not half-upgraded. Contact Flow Software support before upgrading a 5.3.x database; we will rehearse the upgrade on a copy first.
Where to go next#
- Upgrading to Flow 7.2.0 — read before upgrading a production instance
- Deprecations and Breaking Changes
- Complete CLI Option Reference