From ae4169b4cc5f57540a9a1f0b938be31393a1ddf7 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sun, 24 May 2026 07:55:29 -0400 Subject: [PATCH] fix(transport): symmetric blocker-scan fixes in Apply-time validator RunSemanticValidationAsync's Pass 1 minimal-name-resolution scan duplicated DetectBlockersAsync's heuristic but had the same two bugs fixed in the previous two commits: it was scanning TemplateAttribute.DataSourceReference (an OPC UA address-space path, not script source) and it was missing the KnownNonReferenceNames denylist. As a result, an import that passed the diff-step blocker check would still fail at Apply with the same 30+ identifiers reappearing as "Bundle semantic validation failed" errors. Apply the same two fixes here so the diff preview and the Apply-time validator agree. --- src/ScadaLink.Transport/Import/BundleImporter.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ScadaLink.Transport/Import/BundleImporter.cs b/src/ScadaLink.Transport/Import/BundleImporter.cs index f2cbccb..0ad0247 100644 --- a/src/ScadaLink.Transport/Import/BundleImporter.cs +++ b/src/ScadaLink.Transport/Import/BundleImporter.cs @@ -1650,8 +1650,12 @@ public sealed class BundleImporter : IBundleImporter foreach (var s in t.Scripts) CollectCallIdentifiers(s.Code, referenced); foreach (var a in t.Attributes) { + // Value can hold script-callable design-time expressions; + // DataSourceReference is an OPC UA address-space path (e.g. + // "ns=3;s=Tank.Level") and must NOT be scanned, or the dot + // delimiter will flag tag-path segments as missing references. + // Symmetric with DetectBlockersAsync. CollectCallIdentifiers(a.Value, referenced); - CollectCallIdentifiers(a.DataSourceReference, referenced); } } foreach (var m in content.ApiMethods) @@ -1664,6 +1668,7 @@ public sealed class BundleImporter : IBundleImporter foreach (var candidate in referenced.OrderBy(n => n, StringComparer.Ordinal)) { if (!LooksLikeResourceName(candidate)) continue; + if (KnownNonReferenceNames.Contains(candidate)) continue; if (sharedScriptNames.Contains(candidate) || externalSystemNames.Contains(candidate)) continue; errors.Add( $"Script references SharedScript or ExternalSystem '{candidate}' not present in bundle or target.");