Release Notes 2026-07-20

Release Notes 2026-07-20

Version Information

OpenEdge Release

Version Information

OpenEdge Release

Version Information

11.7.21, 12.2.19, 12.8.9, 12.8.11, 13.0.0

Release 11.7 #89339@2026-07-20

Retirement of OpenEdge 11.7

OpenEdge 11.7 has been retired by Progress Software on April 1st 2025. In consequence we urge all customers still using OpenEdge 11 to upgrade to OpenEdge 12.2 or 12.8 as soon as possible.

We are intending to drop the official support of the SmartComponent Library for OpenEdge 11.7 during the second half of the year 2025. We will then no longer ensure that new features of the framework will be usable with OpenEdge 11.7

Customers that are concerned by this intention, should reach out to us as soon as possible, so that we can discuss about a solution.

OpenEdge 13.0 support!

We are pleased to announce that we are not aware of any issues using the SmartComponent Library on OpenEdge 13.0. We hereby declare OpenEdge 13.0 fully supported for the SmartComponent Library as of the release of February 15th 2026.

OpenEdge 12.8 support!

We are pleased to announce that we are not aware of any issues using the SmartComponent Library on OpenEdge 12.8. We hereby declare OpenEdge 12.8 fully supported for the SmartComponent Library as of the release of January 15th 2024.

OpenEdge 12.2 support!

We are pleased to announce that we are not aware of any issues using the SmartComponent Library on OpenEdge 12.2. We hereby declare OpenEdge 12.2 fully supported for the SmartComponent Library as of the release of April 09th 2020.

PASOE / OEMANAGER VS Code Extension

Our first VS Code extension is available in the VS Code marketplace: https://marketplace.visualstudio.com/items?itemName=ConsultingwerkApplicationModernizationSolutionsLtd.oemanager

The extension supports developers with PASOE related routine tasks during development:

  • checking agent or session status

  • trimming the PASOE agents

  • restarting a new agent vai the ping request

Introducing the SmartComponent Library developer forum

Got questions about using the SmartComponent Library? Wish to discuss feature requests with other users of the SmartComponent Library? To facilitate networking in the growing number of SmartComponent Library users and developers, we've added a developer forum on our new home-page. The developer forum can be found at: https://www.consultingwerk.com/support/forum

A login is required to participate in the forum. Don't be shy - create your account today!

Release Notes

Following the release of the OpenEdge 11.7 Release we have completed our testing of the SmartComponent Library on this release of Progress and are proud to announce formal support for the SmartComponent Library on OpenEdge 11.7 with the 2017-04-24 release of the SmartComponent Library. Generally we recommend customers on OpenEdge 11 to upgrade to OpenEdge 11.7 quickly. Starting the 2017-07-14 release we are supporting OpenEdge 11.7 Service Pack 1 (11.7.1).

Starting the 2015-10-09 release the Business Entity Designer will feature a start page with links to most recent release note articles on this site.

With SCL-751 we have adopted native Enums for OpenEdge 11.6. To activate this feature customers must add a definition to products.i. SCL-751 provides details for this.

With SCL-1113 we have modified the templates for SmartWindowForms and SmartTabFolderPages generated from the Business Entity Designer. We have removed the initialization of the viewer controls SmartTableIOState property (value was set to "NoDataSource" within the InitializeComponent method). Customers using their own set of templates should adopt the same fix to their templates.

New Versions of Proparse .NET Assemblies (30 December 2018)

We have updated proparse with further enhancements in this release (see https://github.com/consultingwerk/proparse/releases/tag/4.0.1.1177). Please download the .NET Assemblies ZIP file from our ESD and replace the proparse.net.dll in your environment with the latest one. The new assembly reference is:

<assembly name="proparse.net, Version=4.0.1.1177, Culture=neutral, PublicKeyToken=cda1b098b1034b24"/>

As proparse is used by our Business Entity Generator, this new version of the proparse.net Assembly is also relevant for customers not doing GUI for .NET development and require support for parsing new ABL language constructs.

This version of proparse provides additional debug information when errors are thrown from proparse.net.dll.

New Version of the Consultingwerk.SmartComponents Assemly (09 January 2019)

To support the new SmartFilterControl and the "Filter" link between the SmartFilterControl/SmartDynamciFilterControl and a SmartBusinessEntityAdapter or SmartDatasetChildAdapter we have updated the Consultingwerk.SmartComponents.dll. The new Assembly reference is:

<assembly name="Consultingwerk.SmartComponents, Version=2.2.0.49856, Culture=neutral, PublicKeyToken=10603cb31df311b3"/>

Customers need to update this Assembly in order to compile the latest releases of the SmartComponent Library.

Hybrid Realm now using IAuthenticationService

We've updated the SmartHybridRealm class used for http authentication to leverage the IAuthenticationService. It is therefor required that for AppServers requiring http Authentication (e.g. REST or Web) the correct IAuthenticationService implementation is registered (using service.xml files).

Customers relying on the previous behavior should ensure that the Consultingwerk.SmartFramework.Authentication.AuthenticationService is regsitered as the IAuthenticationService. This implementation will auhtenticate users against the password stored in the SmartUser database table.

When users with no Login Company set should be able to login using the SmartHybridRealm, it's required to set the Login Company Tennant Domain (similar to the field in the Login Company Maintenance) in the .restapplicationsettings / .applicationsettings, e.g.:

 

"DefaultAuthenticationDomain": "consultingwerk"

This is required as the Hydrid Realm Interface from Progress does not provide the domain name to the authentication method.

Web Handler overview

This is an overview of the web handlers supported by this release

defaultHandler=OpenEdge.Web.CompatibilityHandler handler1=Consultingwerk.OERA.JsdoGenericService.WebHandler.CatalogWebHandler: /Catalog/{EntityName} handler2=Consultingwerk.OERA.JsdoGenericService.WebHandler.CatalogsWebHandler: /Catalogs/{PackageName} handler3=Consultingwerk.OERA.JsdoGenericService.WebHandler.CountWebHandler: /Resource/{EntityName}/count handler4=Consultingwerk.OERA.JsdoGenericService.WebHandler.ResourceSubmitWebHandler: /Resource/{EntityName}/SubmitData handler5=Consultingwerk.OERA.JsdoGenericService.WebHandler.InvokeMethodWebHandler: /Resource/{EntityName}/{MethodName} handler6=Consultingwerk.OERA.JsdoGenericService.WebHandler.ResourceWebHandler: /Resource/{EntityName} handler7=Consultingwerk.OERA.JsdoGenericService.WebHandler.BusinessServicesWebHandler: /BusinessServices/{OutputFormat}/{PackageName} handler8=Consultingwerk.Web2.WebHandler.SmartMenuWebHandler: /SmartMenu/{MenuStructureId} handler9=Consultingwerk.Web2.WebHandler.SmartMenuStructureWebHandler: /SmartMenuStructure handler10=Consultingwerk.Web2.WebHandler.SmartRoutesWebHandler: /SmartRoutes handler11=Consultingwerk.Web2.Services.SmartViewsHandler.SmartGridWebHandler: /SmartViews/Grid/{EntityName}/{ViewName}/{DetailTemplate} handler12=Consultingwerk.Web2.Services.SmartViewsHandler.SmartGridWebHandler: /SmartViews/Grid/{EntityName}/{ViewName} handler13=Consultingwerk.Web2.Services.SmartViewsHandler.SmartGridWebHandler: /SmartViews/Grid/{CustomViewName} handler14=Consultingwerk.Web2.Services.SmartViewsHandler.SmartViewerWebHandler: /SmartViewer/Viewer/{EntityName}/{ViewName} handler15=Consultingwerk.Web2.Services.SmartViewsHandler.SmartViewerWebHandler: /SmartViewer/Viewer/{ObjectName} handler16=Consultingwerk.Web2.Services.SmartViewsHandler.SmartFormWebHandler: /SmartForm/{FormTemplate}/{EntityName}/{ViewName} handler17=Consultingwerk.Web2.Services.SmartViewsHandler.SmartFormWebHandler: /SmartForm/{FormTemplate}/{ObjectName} handler18=Consultingwerk.Web2.WebHandler.SmartMessageWebHandler: /SmartMessage/{MessageGroup}/{MessageNumber} handler19=Consultingwerk.Web2.WebHandler.GetImageWebHandler: /Image/{FileName} handler20=Consultingwerk.Web2.WebHandler.SmartValueListWebHandler: /ValueList/{ValueList} handler21=Consultingwerk.Web2.WebHandler.SmartAttachmentsWebHandler: /Attachments/{Table}/{KeyValues} handler22=Consultingwerk.Web2.WebHandler.SmartAttachmentWebHandler: /Attachment/{Guid} handler23=Consultingwerk.Web2.WebHandler.SessionContextWebHandler: /SessionContext handler24=Consultingwerk.Web2.WebHandler.ContextPropertiesWebHandler: /ContextProperties/{PropertyName} handler25=Consultingwerk.Web2.WebHandler.ContextPropertiesWebHandler: /ContextProperties handler26=Consultingwerk.Web2.WebHandler.SessionInfoWebHandler: /SessionInfo handler27=Consultingwerk.Web2.WebHandler.FileSearchWebHandler: /FileSearch/{FileName} handler28=Consultingwerk.Web2.WebHandler.ExecuteAblWebHandler: /ExecuteAbl handler29=Consultingwerk.Web2.WebHandler.SmartLanguagesWebHandler: /Languages handler30=Consultingwerk.OERA.RestResource.RestEntitiesWebHandler: /Entities handler31=Consultingwerk.OERA.Swagger.SwaggerWebHandler: /Swagger/{EntityName} handler32=Consultingwerk.OERA.Swagger.SwaggerRestEntitiesWebHandler: /SwaggerEntities/{OutputType} handler33=Consultingwerk.Web2.WebHandler.SmartTokenSecurityCheckWebHandler: /TokenSecurityCheck/{ObjectName} handler34=Consultingwerk.Web2.WebHandler.SmartTokenSecurityCheckWebHandler: /TokenSecurityCheck handler35=Consultingwerk.Web2.WebHandler.SmartEntityTableMappingHandler: /EntityTableMapping/{EntityName}/{TableName}/{UiTypeCodes} handler36=Consultingwerk.Web2.WebHandler.SmartTreeRootNodeWebHandler: /SmartViews/TreeRootNode/{rootnodeid} handler37=Consultingwerk.Web2.WebHandler.SmartTreeChildNodesWebHandler: /SmartViews/TreeChildNodes/{parentnodeid} handler38=Consultingwerk.Web2.WebHandler.SmartSecurityCheckWebHandler: /IsRestricted/{SecurityRealmCode}/{SecurityItemGuid} handler39=Consultingwerk.Web2.WebHandler.SmartFieldSecurityCheckWebHandler: /RestrictedFields/{TableName} handler40=Consultingwerk.Web2.WebHandler.GetImageNamesHandler: /ImageNames handler41=Consultingwerk.Web2.WebHandler.ExecuteQueryWebHandler: /ExecuteQuery handler42=Consultingwerk.Web2.WebHandler.TranslationProviderWebHandler: /GetTranslation

UTF-8 based deployments available

Starting August 14th 2016 we ship our source code also as UTF-8 encoded. The ZIP files ending with _utf8.zip contain the source code encoded with that code page. The source code in the remaining archives is still encoded in ISO8859-1. Also on Github there is a new branch containing the OpenEdge 11 based source code in UTF-8.

Related article (Progress K-Base): How to get Progress Developer Studio to save in UTF-8 encoding

New Feature Documentation

Download Link

http://esd.consultingwerkcloud.com/

https://github.com/consultingwerk/SmartComponentLibrary

Overview of included tickets

REST endpoints now support media type (Accept header) versioning

The @RestAddress and @RestMethod annotations now accept an optional Accept argument that enables versioning of REST endpoints through the Accept header in the RestEntitiesWebHandler. When the Accept argument is not provided the previous behavior is fully preserved and backward compatible. Endpoint uniqueness is now defined by the combination of URL and media type, so the same URL can route to different methods or Business Entities per media type, and the generated Swagger documentation reflects the documented media types. Each annotation may contain a comma-delimited list of Accept values.

GenericDataExporter can now optionally add a generation timestamp to exported XML files

The GenericDataExporter now supports an optional timestamp recording when the XML file was generated, stored as a separate node with a single DATETIME-TZ field. When comparing the newly generated XML with the file already on disc, the timestamp difference is ignored, so a file is only re-saved when there are actual content changes (a technique similar to CodeGeneratorHelper:HasNonCommentChanges used by the Business Entity Generator). By default the previous behavior is preserved, so no ANT script changes are required; developers who want the timestamp can enable it by passing the corresponding option to the PCTRun that calls the GenericDataExporter.

Proparse Web Service now returns structured JSON error responses on failure

Every REST-exposed method of the Proparse Web Service is now wrapped in a try/catch block that, on failure, returns a JSON response with a 500 status containing the exception error message, stack trace and additional properties. The error format is compatible with the errors returned by the HandleError method in the SmartWebHandler, giving callers consistent, machine-readable error information.

Field grouping support added for field security realms

Field security can now be applied to groups of fields via a new SmartFieldGroup table and the FieldGroupBusinessEntity. The SmartFieldAuthorizationProvider now evaluates two new security realms, SFGH (Smart Field Group Hidden) and SFGS (Smart Field Group Sensitive), so that hiding or disabling can be configured for a whole field group instead of individual fields. Group boxes whose contained fields are all hidden by security are now hidden automatically, in both .NET viewers and the repository-based Web rendering. Developers assign a field group in the SmartFieldSecurityItem maintenance and manage the groups in the new field group maintenance form.

Inherited menu security for groups is now indicated in menu security maintenance

The menu security maintenance now indicates the privileges that a user group inherits from its parent groups, showing such entries as restricted-by-parent-group instead of leaving inherited restrictions invisible. This makes it easier to understand why a menu item is restricted for a given group.

Automated unit test added for the PASOE OE Manager wrapper (PasoeManager)

Added an automated unit test for Consultingwerk.Studio.Pasoe.PasoeManager, the class that wraps the PASOE oemanager REST API. The test covers the read-only operations GetApplications, GetMetrics, GetAgents and GetAgentSessions and runs against the PASOE Docker container in the Linux REST API stage of the pipeline. No changes required in customer code.

Business Entity queries can now filter and sort by fields from related database tables

Business Entity data access can now filter and sort by fields that live on related database tables, even when those fields are not part of the temp-table. A new AddAdditionalSourceColumn API on Consultingwerk.OERA.DataAccess registers a mapping from a temp-table field reference to a database field, and the referenced table is joined dynamically for the duration of the request. An optional OptimizeSourceQuery property lets the DataAccess reorder the source query buffers for better index bracketing. Both features are opt-in and leave existing Business Entities completely unchanged when not enabled.

Improved: RepositoryData folder selection in product module maintenance now uses the server-side folder picker

The Data Folder selection in the product module maintenance (Consultingwerk.Windows.Framework.Menu.SmartModuleViewer) now uses the server-side folder picker control Consultingwerk.Windows.Controls.SmartFilePickerEditor instead of the client-side FolderBrowserDialog. A new folderbrowserscopes entry named repositorydata was added to the .applicationsettings and .restapplicationsettings, scoped to the RepositoryData folder. Developers can now select paths outside the working directory, with validation for relative paths.

Menu functions can now be grouped for authorization via the new SMFG security realm

Multiple menu functions can now be grouped and authorized together through a new SmartFunctionGroup table and the new SMFG (Smart Menu Function Group) security realm, mirroring the existing field group approach. A FunctionGroupBusinessEntity, its repository objects (data source, lookup, MetaViewer, MetaGrid, form) and a FunctionGroupSecurityService were added. Wherever the framework checks the SMF menu security realm it now additionally treats a function as restricted when its FunctionGroupGuid is restricted under SMFG. Developers assign a function to a group via the new FunctionGroupGuid foreign key on SmartFunction; follow-up steps such as creating SmartTable/SmartRelation records and registering the SMFG realm are performed manually.

Query predicate classes now use OpenEdge 13 generic types with an OpenEdge 12 fallback

On OpenEdge 13 the table query predicate classes can now use generic types (e.g. GenericCharacterPredicate<CustomerQuery>) instead of the generated per-table predicate files, dramatically reducing the number of generated files. Conditional compilation via &IF DEFINED(OpenEdge_13_0) keeps a single codebase backward compatible with OpenEdge 12, and generic generation remains configurable through a static property on the generator class. An ANT script and a new button on the Table Query Plugin Generate tab are provided to remove the no-longer-required files from an OpenEdge 13 codebase.

Improved logging and consistency checks for REST .annotations, .xsd and .cls files

When reading .annotations files during RestResourceService initialization, sanity checks now report inconsistencies as warnings in the AppServer logfile: non-existing referenced methods, @RestMethod annotations with DATASET parameters lacking a matching @ParameterSchema, @ParameterSchema references to non-existing XSD files, and dataset name mismatches between the annotation and the XSD. Classes that exist but do not implement ISupportsRestAddress/ISupportsRestMethods are now logged instead of being skipped silently. A code quality unit test performs the same scan across all REST resource classes and fails listing any reported issues.

Business Entity Tester now supports testing update (Submit) operations

The OERABusinessEntityTesterUserControl now offers an Update record action to test the update (Submit) operations of a Business Entity, including its update-related logic and linked classes such as the DataAccess validation and before-save logic. The action is available in both hosting tools (the UltraBusinessEntityTesterForm and the BusinessEntityBrowserForm) as a toolbar/Ribbon button and as an Edit/Update record entry in the data grid context menu. The actions are only enabled when the grid currently contains a record.

Security Assignment Maintenance now supports editing the Login Company

Administrators can now change the Login Company of a security assignment directly in the SmartSecurityAssignmentViewerControl instead of logging out and back in with a different company. A new static property AllowAssignmentInOtherLoginCompany on the SecurityService class (exposed through ISecurityService, the SecurityRealmInfoBusinessTask and a @RestMethod for the Angular client) controls whether the new Login Company lookup is enabled. The SecurityAssignmentBusinessEntity validates that assignments are only created or updated for permitted companies.

New RefreshAfterSaveChanges option refreshes adapter data after SaveChanges

A new RefreshAfterSaveChanges property on Consultingwerk.SmartComponents.Base.SmartDatasetAdapter (the shared base of SmartBusinessEntityAdapter and SmartDatasetChildAdapter) triggers a RefreshData call after changes have been saved to the backend. This supports Business Entities that update further records during SaveChanges, for example renumbering a position field to close gaps, so the front end stays in sync. The option is supported by the GUI for .NET adapters and the web rendering; enable it on the adapter to activate the behavior. Angular front end support is tracked separately in SCLNG-1704.

ErrorHelper:FormattedErrorMessagesExt now includes custom error properties

Consultingwerk.Util.ErrorHelper:FormattedErrorMessagesExt now uses reflection to render the custom properties of ABL error classes (extending Progress.Lang.AppError) in a tabular form between the error messages and the stack trace. Only custom properties are shown; properties defined in Progress.Lang.AppError and its base classes are excluded, and object properties are reflected recursively and rendered indented. No changes are required in customer code to benefit from the richer output.

GetInstance and typed Get...Instance methods added to SmartWindowForm and SmartFormLogic

SmartWindowForm and SmartFormLogic now provide GetInstance and typed accessor methods (e.g. GetSmartViewerControlInstance, GetSmartBusinessEntityAdapterInstance, GetSmartDataBrowserInstance) with the same signatures as those in DynamicForm, which now override them. SmartWindowForm resolves controls and adapters via the ControlHelper, while SmartFormLogic delegates to its Owner. Developers can retrieve named component and control instances from static forms.

ToList method added to the IQueryExpression interface

A new ToList method was added to the Consultingwerk.IQueryExpression interface and all implementing classes, returning a ListQueryExpression. In ListQueryExpression it returns the list itself; in all other implementations it returns a new list containing the current expression. This lets developers uniformly treat single expressions and lists in their code.

Fixed: QueryParser now correctly parses query strings containing tab characters before AND/OR/BY tokens

Tab characters (chr(9)) are now sanitized like CR and LF in Consultingwerk.QueryParser:ParseQueryString, so filter query strings with tabs surrounding the AND, OR or BY tokens parse correctly instead of failing. No changes required in customer code.

QueryParser parsing performance improved by reducing per-term and per-character overhead

The Consultingwerk.QueryParser and StringHelper classes were optimized to reduce redundant substitute() calls and character-by-character loops during query string parsing. ParseTerm and ParseQueryString now guard function-name probing with cheap single-character checks, and ResolveDoubleQuotes/FindClosingQuote use index()-based fast paths. The existing parsing behavior is fully preserved and no changes are required in customer code.

Fixed: Groups grid now refreshes the Parent Group Name after committing parent group changes

Fixed a bug in the SmartGroup maintenance form where the groups grid kept showing the previous Parent Group Name after committing parent group assignment changes on the Parent Groups tab. The grid now calls RefreshData after the commit so the updated Parent Group Name is shown immediately. No changes required in customer code.

Optimized QueryString parsing and generated SourceColumn lookup in the DataAccess FetchData path

The QueryString query parser and the generated SourceColumn method were optimized. ParseQuery now computes the query length once, reuses the lookahead buffer for the current character, and uses an integer range check for digit classification, while UnescapeKnownFunctions only iterates the populated entries. The Business Entity Designer dataaccess template was updated so the generated SourceColumn performs the DATA-SOURCE-COMPLETE-MAP lookup once instead of twice. Regenerate DataAccess classes from the Business Entity Designer to pick up the improved SourceColumn implementation.

Reduced per-request query string processing overhead for filtered GET requests in RestEntitiesWebHandler

Query string handling for filtered GET requests in the RestEntitiesWebHandler was optimized. The reserved query names offset, limit, sort and fields are now discarded at the top of the FilterString loop before the operator-token scan and value retrieval run, and repeated URI query-map lookups (HasQueryName/GetQueryValue pairs) were reduced. Observable behavior is unchanged. No changes required in customer code.

Reduced @RestMethod invocation overhead in RestEntitiesWebHandler

The @RestMethod invocation path of the RestEntitiesWebHandler was made leaner. The response ContentType is no longer rebuilt twice per request, as the re-assignment is now guarded against the current value across all five verb handlers (GET, POST, PUT, PATCH, DELETE), and query string parameter mapping now probes the request URI once per property instead of twice. Observable behavior is unchanged. No changes required in customer code.

Reduced per-call overhead in ServiceContainer and ServiceManager service resolution

Service resolution through the ServiceContainer and the ServiceManager was optimized in the hot path. A get-service.i expansion with a default implementation no longer resolves the service twice, a flag on the service record avoids a dynamic type check for lazy-loading creators, and the static ServiceManager facade now caches its IServiceManager implementation instead of resolving it on every static call. These building blocks are used by every get-service.i expansion and every Business Entity and Business Task access, so the savings apply broadly. Lazy creation and life-cycle management remain unchanged, and new unit tests cover the optimized code paths. No changes required in customer code.

Reduced per-request overhead of ContextDatasetStore and JsonContextDatasetStore

The XML ContextDatasetStore and JsonContextDatasetStore, which run on every AppServer request, were optimized to reduce avoidable per-request cost. The IClientPrincipalParser service is now cached in the store instance, the eSessionContext buffer handle is cached, log-message construction is guarded by an active-log-entry-type check, and repeated LONGCHAR length evaluation was removed. Functional behavior is unchanged and new unit tests guard the store and restore round trip. No changes required in customer code.

Fixed: SmartBusinessEntityLookup now clears its display text when navigating to a record with an empty key

Fixed a bug where a data-bound SmartBusinessEntityLookup with FetchDataFromKeyValueOnNavigate enabled kept showing the previous record's display text when navigating to a record whose bound foreign-key value is empty. FetchDataFromKeyValue now clears the displayed text for an empty or unknown key without a backend round-trip and without modifying the current row. No changes required in customer code.

Menu Security Maintenance now supports maintaining Default (Everybody) security assignments per menu function

The User and Group selection dialog (SmartUserAndGroupSelectionForm) now offers a Default (Everybody) entry, allowing developers to maintain the security assignment records that have neither a UserGuid nor a GroupGuid set directly from the menu security maintenance treeview (SmartMenuSecurityMaintenanceControl). The backend services AuthorizationMaintenanceService and MenuAuthorizationMaintenanceService were extended to create, update, and delete these Everybody-level assignment records. This complements the existing runtime authorization precedence (User, Group, Parent Group, Everybody, Realm default), so administrators can manage the Everybody baseline for each menu function without editing records manually.

New GitBranchesControl added, showing a Git branch overview in CustomerExplorer, Business Entity Designer and Desktop forms

A new user control Consultingwerk.Studio.Git.GitBranchesControl displays the local Git branches of the current workspace in an UltraGrid, showing the current branch, remote status (Yes/No/Gone) and last commit timestamp, with color-coded rows (current branch green, gone remotes yellow). Branch information is retrieved through the git command line via the extended BranchInfoProvider infrastructure in the Consultingwerk.Studio.Git package, and the control fails silently with logging when Git information cannot be fetched. It is integrated into the CustomerExplorer and Business Entity Designer start pages next to the Release Notes panel, and can be opened from the status bar in Desktop Form 2 and the Legacy GUI FRAME and BROWSE Migration Forms.

TableModel API methods now document their TableModelType-dependent behavior

The Javadoc comments of the mode-dependent methods in Consultingwerk.OERA.TableModel now explicitly state how each method behaves per TableModelType (BufferModel vs Table/QueryModel), including whether it throws NotSupportedException, returns false, or returns unknown. This is a documentation-only change with no runtime behavior differences. No changes required in customer code.

Configuration files can now fail fast on unresolved ${env.*} substitution tokens

A new optional boolean property validateSubstitutionVariables at the root of a JSON configuration file enables validation that reports any surviving ${env.*} tokens after variable substitution, naming the token and the file so that a missing or misspelled environment variable fails at startup instead of surfacing later as an unrelated error. When the property is absent or false, resolution behavior is unchanged. The variable substitution feature and the new property are documented on the JSON Configuration File Format page.

Server-side AfterRetrieveData event now follows the standard EventHandlerParameter convention

The AfterRetrieveData server-side event handler no longer requires manual JSON deserialization of its EventContext. New first-class QueryString and Available properties were added to EventHandlerParameter and IAfterRetrieveDataEventHandlerParameter, EventContext now carries a plain Available/NotAvailable scalar, and SelfName carries the adapter InstanceName. Handlers can read these values directly instead of parsing the context with ObjectModelParser. The demo handler and interface documentation were updated accordingly.

Menu Function Maintenance can now be opened directly from the Menu Structure Maintenance ribbon

A new ribbon button was added to the Menu Structure Maintenance form (SmartMenuMaintenanceForm) that opens the Menu Function Maintenance form (SmartFunctionMaintenanceForm) and navigates it to the menu function referenced by the currently selected menu structure tree node. The button is enabled only when the viewer is not adding or updating a record and the selected node references a menu function. If the Menu Function Maintenance has a pending update, RepositionToMenuFunction now reports this so the user is asked to cancel the pending change and try again.

Width support added to the SSEH FieldControl response contract and GUI for .NET grid columns

The SSEH FieldControl response contract now supports an optional numeric Width value (in CSS pixels) that lets a front end change the rendered width of the field or column identified by FieldName. In GUI for .NET, the SmartGridUiControlHandler used by SmartDataBrowser and SmartUpdatableBrowser applies the Width and Label of a returned FieldControl to the matching UltraGridColumn, resolving both unqualified (Name) and qualified (Customer.Name) field names. Width is optional and fully backward compatible: responses without Width behave exactly as before, and a FieldControl referencing a column that does not exist in the grid is skipped without raising an error. Frontend consumption of FieldControl.Width in Smart Grid columns is tracked separately in SCLNG-1721.

Fixed: Silent loss of non-BMP characters on OpenEdge 12.2 is now detected in JsonHelper and CodepageHelper

The bug where OpenEdge 12.2 silently replaced characters outside the Basic Multilingual Plane (such as emojis) with "?" instead of raising a conversion error - causing undetected data loss - has been fixed. CodepageHelper:ConvertToCodepage and CompliesWithCodepage now perform a round-trip comparison to detect the silent substitution on releases before OpenEdge 12.8, and JsonHelper:AssignBufferFieldFromJson either strips the unconvertible characters (when plIgnoreIncompatibleCharacters is true) or throws an exception, matching the strict behavior of OpenEdge 12.8 and 13.0. Two related side issues in the character-conversion catch blocks were also corrected. No changes required in customer code.

Fixed: ProparseDotNetNode:Query now handles large node result arrays on OpenEdge releases before 12.8

The bug where ProparseDotNetNode:Query failed with error 5729 on OpenEdge releases before 12.8 when converting large .NET arrays (more than roughly 850 elements) into an ABL EXTENT has been fixed. On releases before OpenEdge 12.8, ProparseDotNetNode:Query now keeps the .NET array as a System.Array object reference and fetches elements individually via GetValue, while OpenEdge 12.8 and 13.0 keep the existing bulk conversion. No changes required in customer code.

Fixed: Data Dictionary dump now works on OpenEdge 12.2 by guarding online-schema shared streams

Fixed the customized Data Dictionary dump (ProdictDumpHack) producing no output at all on OpenEdge 12.2. The online-schema shared stream definitions in Consultingwerk/Studio/user-env.i are now guarded so they are only referenced on releases whose dictionary programs actually create those streams. No changes required in customer code.

Fixed: web handler query string parameters now decode correctly on OpenEdge 12.2

Fixed web handler query string parameters (such as filter) failing to parse on OpenEdge 12.2, where OpenEdge.Net.URI:GetQueryValue returns still percent-encoded values before release 12.4. A new GetDecodedQueryValue helper on SmartWebHandler decodes values on releases before 12.4 and passes them through unchanged on 12.4 and newer; all affected web handlers now use it. No changes required in customer code.

Fixed: Proparse and PASOE Agent Telemetry Docker tests are skipped on OpenEdge releases before 12.8

The Proparse web service and PASOE Agent Telemetry web applications are built Jakarta EE native and require a PASOE with Tomcat 10, i.e. OpenEdge 12.8 or newer. Their Docker tests are now skipped on releases before 12.8, where the web applications cannot load on Tomcat 9. No changes required in customer code.

Fixed: READ-JSON empty-record test now recognizes the OpenEdge 12.2.17 backport

Fixed the READ-JSON empty-record unit test version gates to account for the READ-JSON fix that Progress backported to OpenEdge 12.2.17. Service pack level 17 and newer on the 12.2 line are now treated as post-fix behavior. No changes required in customer code.

Fixed: BadInputException test now accounts for lenient query evaluation on OpenEdge 12.2

Fixed a unit test that expected a BadInputException from a dynamic query comparing an integer field to a non-numeric string. OpenEdge 12.2 evaluates such comparisons leniently and raises no error, so the test now asserts the version-specific behavior (error expected on 12.8 and newer, no error on older releases). No changes required in customer code.

Fixed: intermittent SNI unit test now uses a stable strict-SNI endpoint on OpenEdge 12.2

Fixed an intermittently failing SmartHttpClient SNI unit test that depended on an external endpoint whose TLS edge did not complete the handshake with the OpenEdge 12.2 TLS stack. The test now targets a stable strict-SNI endpoint under Consultingwerk control, so it still genuinely verifies the SNI feature. No changes required in customer code.

Fixed: SmartHttpClient now sets the correct SNI host when following redirects across hosts

Fixed the SmartHttpClient SNI defaulting so that the Server Name Indicator is updated for every hop when the OpenEdge HttpClient follows a redirect to a different host. The defaulting was moved into an Execute override on SmartHttpClientLibrary, which runs for each hop; an explicitly set ServerNameIndicator is still never overridden and IP address literals still receive no SNI. No changes required in customer code.

SmartUnit can now report overall test progress across parallel test suites

SmartUnit can now report the total number of test methods executed across all parallel test suites of a build. When enabled through a PCTRun parameter, each suite appends a byte to a .count file for every started test method, and the summed file sizes give the overall progress written to the Jenkins log. The feature is fully optional and produces no .count files unless the parameter is set.

Added: Business Entity Designer support for the DataAccess OptimizeSourceQuery property

The Business Entity Designer now supports the new DataAccess property OptimizeSourceQuery. A toggle box for the property was added to Consultingwerk.BusinessEntityDesigner.UI.BusinessEntityViewerControl (below the SourceDefaultQuery editor), backed by a new OptimizeSourceQuery field on the eBusinessEntity temp-table. When enabled, the designer generates or updates the this-object:OptimizeSourceQuery assignment in the DataAccess class constructor during both initial generation and regeneration, whether the property stands alone or is part of a combined assign statement. The IProparseApi service is used to locate the existing assignment. Developers can now toggle query optimization for a Business Entity directly in the designer instead of editing the DataAccess constructor by hand.

Removed: Sparx Enterprise Architect interop assembly (Interop.EA) from the SmartComponent Library ABL project

The Sparx Enterprise Architect COM interop assembly (Interop.EA), which was only used by the Productivity Suite, has been removed from the SmartComponent Library ABL project. The assembly entry, the ABL/Assemblies/EA folder and the related packaging entries were cleaned up. The Productivity Suite keeps its own reference. No changes required in customer code.

Replaced: Windows API Code Pack dependency removed in favor of a pure ABL taskbar ApplicationId implementation

The Microsoft Windows API Code Pack assemblies have been removed from the product and replaced with a pure ABL implementation. A new SetCurrentProcessAppUserModelId helper in Consultingwerk.Windows.API.Win32 calls the shell32.dll SetCurrentProcessExplicitAppUserModelID function directly (passing the AppID as a null-terminated UTF-16 memptr) to group the application's windows under their own taskbar icon. GuiClientStartupManager and the tool launcher start procedures now use this helper instead of the Code Pack. This eliminates a third-party license dependency; no changes required in customer code.

Improved: SmartTable metadata validation now skips tables without mandatory or add-only column metadata for faster saves

The SmartTable metadata validation performed during save operations now skips tables that carry no MandatoryColumns or AddOnlyColumns metadata. The find in Consultingwerk.SmartFramework.SmartDataAccess:ValidateSmartTableMetadata now filters on these columns, so tables without validation metadata return early instead of being evaluated per row. This gives a small per-row performance improvement on every save through a SmartDataAccess subclass. No changes required in customer code.