Skip to content

Dive Into APEX

Old dog, new tricks.

  • Blog Archive

Tag: Metadata

Mending Metadata Mismatches

Use apex validate to find and fix inconsistencies in mature apps

Mending Metadata Mismatches

One Small Step with APEXlang introduced apex validate, the new way to check the integrity of your app metadata. Apps created in recent APEX releases will likely pass without issues. Mature apps, however, may contain inconsistencies that are now easy to find and fix. This article walks through four examples, their likely causes, and how to address them. Along the way, you’ll learn an approach for triaging other kinds of metadata issues, too.

NOTE: To see any image at full size, right click it and open it in a new tab.

Discrepancies Dispatched Automatically

On import and instance upgrade, APEX fixes a number of common issues that would fail the strict metadata verification apex validate performs. We studied a large internal APEX instance with nearly 80,000 apps. Some apps there have been in service for over 15 years. This helped us identify and classify typical real world cases. We proactively repair the ones we can reliably identify and fix unambiguously.

Among these automatic repairs, we remove illegal…

  • list items for non-static lists
  • LOV entries for non-static LOVs
  • dynamic action steps configured as False actions when event handler has no client-side condition
  • A handful of wizard-generated incorrect template options
  • tabform DML page processes on pages with no tabform region
  • grid DML page processes pages with no grid region

We clear a validation’s associated item when it illegally references a page item on a different page that’s not the global page.

We also fix bad button ID references when the incorrect button on another, non-global page has same button name as the intended button on the current page. We correct the following situations:

  • When Button Pressed conditions on page processes, branches, validations, and
  • Triggering button for dynamic action events

When possible, the fix updates the wrong reference to be the ID of the intended button on the same page. When the current page has no button with the same button name, we convert the When Button Pressed condition into the equivalent “RESULT = BUTTON_NAME” condition, but only if the element is not already using its Server-side Condition for another purpose.

You can diagnose and address any inconsistencies that may remain using the techniques explained in the rest of this article.

Validating Your App Using SQLcl

Start by connecting SQLcl to the parsing schema of your workspace. Here I’m using a named connection to connect, but you can connect any way you like.

% sql -name diveintoapex
SQLcl: Release 26.1 Production on Sun May 17 15:32:25 2026
Copyright (c) 1982, 2026, Oracle. All rights reserved.
Connected to:
Oracle AI Database 26ai Free Release 23.26.0.0.0
SQL>

Then, export your application in APEXlang format:

SQL> apex export -applicationid 173 -exptype apexlang
Exporting Workspace DIVEINTOAPEX - application 173:HR App
File hr-app/application.apx created

Finally, use apex validate to verify the app. Use the ‑input argument and specify the relative path to the directory just created by the export. It’s named hr-app in my example after the app alias. If you downloaded the APEXlang from APEX Builder, you can also specify a path to a zip file. The spool command just before and after apex validate lets you save any errors in a log file to review later.

SQL> spool hr-app.log
SQL> apex validate -input hr-app
APEXLang Compile Errors:
File: pages/p00003-employee.apx
Line: 421
Column: 16
Type: LOV_NOT_FOUND
Error: Invalid LOV required parameter: settings - options (string)
Valid parameters are:
-cacheResult
-disableArrow
-escapeHtml
-followCursor
-interactiveText
-showOnCreation
⋮
SQL> spool off

This gives you an hr-app.log text file containing all the errors to investigate.

Validating Your App Using APEX Builder

Alternatively, you can use APEX Builder to export your app in APEXlang format, and then try to import it again. As shown below, if there are any validation errors, you can browse and click the Download link to get an apexlang‑errors.csv file containing all the errors.

Reviewing & Downloading APEXlang Validation Errors During an App Import Attempt

Fix Either in APEX Builder, or in APEXlang

As we explore four metadata mismatch examples, keep in mind that you can apply the fixes either:

  • Using the APEX Builder, then re-exporting in APEXlang to re-validate, or
  • Directly in the APEXlang files.

To use the APEX Builder approach, either your existing app was already in your workspace prior to the APEX 26.1 upgrade, or you can import it using your latest copy of its SQL format export.

Wrong Refs After Page Copy in Old Releases

Older APEX releases had a page-copy bug. Builder cloned the page, but button references in the copied page could still point to the original page. The bug has been fixed for several years now, but apps in service for longer may still carry some incorrect references. The figure below illustrates the problem.

Illustration of Incorrect Button Reference After Page Copy in Older APEX Builder Versions

This problem can involve page processes, branches, and validations with When Button Pressed conditions, as well as dynamic actions that were triggered by a button click. While button-triggered events did not fire at runtime in this situation, the other features did work correctly. Why?

When evaluating the When Button Pressed condition, APEX runtime checks the RESULT system variable for the name of the button, rather than relying on the button ID. This explains why this inconsistency could go unnoticed.

In the app we’re studying, the issue surfaces as the following APEXlang compiler error:

File: pages/p00005-manager.apx
Line: 448
Column: 12
Type: REFERENCE_NOT_FOUND
Error: Reference not found: @/begin-self-eval

If we open p00005‑manager.apx in VS Code, we can press (Ctrl)-G and type in 448 followed by [Enter] to jump to that line. It’s an Initiate Self-Evaluation page process triggered by a button with identifier begin‑self‑eval. Since the incorrectly referenced button was on a different page, its reference uses the @/ prefix: @/begin‑self‑eval. However, we don’t find any button named begin‑self‑eval in this page.

Investigating the “Reference not found” Error in VS Code

Searching the file for a button with -eval at the end of the name, we notice the button got renamed after the original page copy to INITIATE_SELF_EVAL with the initiate-self-eval identifier.

Searching the Page for the Intended Button Name to Trigger the Page Process

To fix the problem in APEXlang directly, we just need to modify @/begin‑self‑eval to be @initiate‑self‑eval, changing the referenced button name and removing the slash.

Once we know the issue relates to the Initiate Self-Evaluation page process in page 5, we can alternatively study and fix the problem in the APEX Builder using Page Designer. The Property Editor shows the value of the When Button Pressed property as 41870290932227811 (Invalid). That long number is the internal ID of the incorrect button reference due to the page copy bug from a long time ago.

Invalid Button Reference Displays ID and “(Invalid)” in Property Editor

Fixing the problem in Page Designer is just as easy. As shown below, choose the INITIATE_SELF_EVAL button name from the list and save the page.

Fixing an Invalid When Button Pressed Reference in Page Designer

Orphaned Authorization Scheme Refs

Another common metadata mismatch involves components referencing an authorization scheme that no longer exists. This is the case for all of the REFERENCE_NOT_FOUND errors below.

File: shared-components/lists.apx
Line: 83
Column: 12
Type: REFERENCE_NOT_FOUND
Error: Value not found: 44263289337994936
File: shared-components/lists.apx
Line: 180
Column: 12
Type: REFERENCE_NOT_FOUND
Error: Value not found: 44263289337994936
File: pages/p01000-administration.apx
Line: 13
Column: 8
Type: REFERENCE_NOT_FOUND
Error: Value not found: 44263289337994936
File: pages/p01000-administration.apx
Line: 95
Column: 12
Type: REFERENCE_NOT_FOUND
Error: Value not found: 44263289337994936
File: pages/p01000-administration.apx
Line: 116
Column: 12
Type: REFERENCE_NOT_FOUND
Error: Value not found: 44263289337994936

Studying line 83 of shared-components/lists.apx, we find a security.authorizationScheme property in an Administration entry in a Navigation Menu list. This property has the raw ID value 44263289337994936 from the imported application since APEX couldn’t find an authorization scheme with that ID.

Missing Authorization Scheme Referenced Using Its Raw Component ID

Studying the sample list entry in APEX Builder, we see the raw ID displays for a missing Authorization Scheme.

Missing Authorization Scheme Displays Using Its Raw Component ID

When a referenced authorization scheme ID is missing, is_authorized returns true so the app behaves as if no authorization scheme were applied. So, presumably the references to the missing scheme went unnoticed if every user was intended to access them. However, if the actual goal was to enforce an authorization check, then a different fix is needed.

If you decide to remove the authorization check, in APEXlang files you can remove the security.authorizationScheme property, along with the group if there are no security properties left.

The equivalent change in APEX Builder is to set the orphaned authorization scheme reference to – No Authorization Required – in the list.

If instead you decide to enforce an authorization check, you can add a new authorization component to the shared-components/authorizations.apx file, and then bulk update the .apx files referencing 44263289337994936 to replace that by the @-sign-prefixed identifier of the new authorization you create.

The equivalent fix in APEX Builder would be to create a new Authorization Scheme, and then visit the different edit pages for the referencing components and choose the newly created authorization scheme. You would fix references to the new scheme within pages using the Property Editor in Page Designer.

Conditions Not Met for Reference

Sometimes a component reference has additional validity constraints. For example, both a Faceted Search and a Smart Filters region have a filteredRegion property. It must reference a region in the current page whose region type supports being facet-filtered: calendar, cards, classicReport, or map.

When a validation error contains “Conditions not met for reference”, it means some aspect of the required constraint was not satisfied.

File: pages/p00006-employees-search.apx
Line: 283
Column: 12
Type: REFERENCE_NOT_FOUND
Error: Conditions not met for reference: @departments

Checking the p00006-employees-search.apx page, at line 283 we find the culprit:

departments Region Does Not Fully Satisfy the Requirements to be Valid Filtered Region

By searching, or using the Outline pane as shown below, we can inspect the properties of the referenced departments region. There, we see it’s an interactiveReport region, which is not one of the kinds of region that can be facet-filtered.

Navigating to Inspect the Properties of the departments Region in VS Code

How did this happen? For example, a developer could create a working Smart Filters region that filtered a Classic Report. Later, they changed the filtered region to be an Interactive Report.

But why wasn’t this causing a problem in the original app? It’s easy to see in Page Designer. The lined-through region names in the rendering tree indicate the Search Departments Smart Filters region and the Departments Interactive Report region are both commented out. This means APEX ignores them during page rendering.

Observing Two Regions are Commented Out in Page Designer

When components in a page are commented out, they have a build option named Commented Out applied. In fact, if you have a second look at the two previous VS Code screenshots, you’ll notice the following in both:

  ⋮
    config {
       buildOption: @commented-out
    }
  ⋮  

APEXlang applies strict validation on every component, including the ones with build options applied to them. So, here the fix to apply is either:

  • Deleting the Departments and Search Departments regions if they aren’t really used any more, or
  • Changing the type of the Departments region to be a Classic Report or one of the other kinds that support facet filtering.

Illegal Defaults from a Plug-in

The last error is of type LOV_NOT_FOUND. It says the settings.options property at line 421 of p00003‑employee.apx does not correspond to one of the expected values.

File: pages/p00003-employee.apx
Line: 421
Column: 16
Type: LOV_NOT_FOUND
Error: Invalid LOV required parameter: settings - options (string)
Valid parameters are:
-cacheResult
-disableArrow
-escapeHtml
-followCursor
-interactiveText
-showOnCreation

Reviewing the page in VS Code, we inspect line 421. The options property of a FOS Tooltip dynamic action step related to the on-page-load dynamic action has the value: cache-result,escape-html

Dynamic Action Step Using FOS Tooltip Plug-in Has Illegal Value for options Property

This is an open-source dynamic action plug-in developers use to add a fancier runtime tooltip to their pages like this:

FOS Tooltip Dynamic Action Plug-in In Action in the Employee Page

To get more info on the valid values for this custom attribute of the FOS Tooltip plug-in, we can either study it in the APEXlang format or in the APEX Builder.

Opening the custom-attributes.apx file for the fosTooltip plug-in, we see the situation below. The string cache-result,escape-html is the default value the plug-in developer configured for this options custom plug-in attribute.

Examining optionsCustom Attribute of FOS Tooltip Plug-in in APEXlang Format in VS Code

Reviewing the same custom attribute in the Builder plug-in edit page, we see the same Default Value for the Options custom attribute.

Reviewing the Same FOS Tooltip Plug-in options Custom Attribute in APEX Builder

Either way you investigate, you discover that the options custom attribute is of type checkboxes. This means it can accept multiple values. The standard delimiter between multi-valued options is the : colon character, but here the plug-in developer has inadvertently used the , comma instead. Their obvious intent was to configure the default set of options to be both Cache  Result and Escape  HTML choices from the LOV.

The plug-in works correctly at runtime since its code tests for which options are specified using the instr() function. For example, it checks for the Cache Result option in the property value using:

l_cache boolean := instr(l_options, 'cache-result' ) > 0;

However, APEXlang performs strict validation, so the fix entails two parts:

  • Part 1: Change the plug-in options custom attribute to have the default value of cache‑result:escape‑html with the : colon delimiter instead.

This will address any new usages of the plug-in in this app.

The second part of the fix requires adjusting how page 3 references the two options values from the custom attribute’s list of valid choices.

  • Part 2: Change the plug-in usage on Page 3 to reference the distinct choices correctly

To fix the default value in Builder, update the default value on the edit page above to use cache‑result:escape‑html and apply the changes.

To fix the plug-in usage on page 3, open Page Designer and select the dynamic action. Notice that due to the illegal comma-separated default value, Page Designer is not showing any values currently checked in the Options checkboxes group. To fix the values, just check the Cache Result and Escape HTML checkboxes, then save the page.

Reviewing FOS Tooltip Dynamic Action Plug-in Options in Page Designer

Alternatively, to fix in the APEXlang files, we would need to update the default value of the custom attribute in FOS Tooltip’s custom-attributes.apx file to be:

⋮
customAttribute attribute_14 (
apexlangName: options
attribute: 14
name: Options
type: checkboxes
appearance {
sequence: 140
}
default {
value: cache-result:escape-html
}
help {
helpText: <p>Additional options to adjust the plug-in even more.</p>
}
)
⋮

Then, we would update page 3 to change the value of the options property to an APEXlang array like this. Between opening and closing square brackets, list each value on its own line: cacheResult and escapeHtml.

      ⋮
       action plugin-com-fos-tooltip (
            action: plugin/fosTooltip
            settings {
                staticContent: Enter the date of hire
                options: [
                    cacheResult
                    escapeHtml
                ]
            }
            affectedElements {
                selectionType: items
                items: P3_HIREDATE
            }
            execution {
                sequence: 10
            }
        )
      ⋮

Summary

Hopefully, studying these examples gives you the techniques to find and fix any metadata inconsistencies your apps may have accumulated over the years.

Start by producing a list of any validation errors and warnings using spool with apex validate in SQLcl, or by downloading the error CSV from APEX Builder import.

Then for each error or warning message:

  • Visit .apx file and line number to understand which component is affected
  • Review it in the familiar APEX Builder for more context
  • Decide on the fix and make it in Builder or directly in the .apx file

After making some fixes, “rinse and repeat” to get an updated list of errors. Enjoy the warm glow that may wash over you once your app validates cleanly!

Unknown's avatarAuthor Steve MuenchPosted on May 19, 2026May 19, 2026Tags APEX 26.1, APEXlang, Metadata

Dive Into APEX: Old Dog, New Tricks

with Steve Muench,
member of the APEX Dev team.

Working hard since 1990 to make Oracle tools the easiest way to build database-backed business apps.

  • Twitter
  • Mail
  • Mastodon
  • Blog Archive
Dive Into APEX Create a website or blog at WordPress.com

Loading Comments...