[#186] Fix "Internal Error" in mapping Sample Source / Single Record Reconciliation when first property has no source#188
Open
vharseko wants to merge 4 commits into
Open
Conversation
…penIdentityPlatform#186) Build the sample-search URL via a new buildSearchUrl helper that derives _sortKeys from the first non-empty property and omits the parameter entirely when no usable property exists, so an empty "_sortKeys=" can never be sent to the CREST/IDM backend. Filter out properties without a source/target in mapping sample search (OpenIdentityPlatform#186) SingleRecordReconciliationView, AttributesGridView and DataAssociationManagementView now keep only properties that actually define a source (and target), preventing a leading undefined value from breaking the sample search query. MappingUtils.setupSampleSearch compacts the property list and guards selectize valueField/searchField against undefined. Add SearchDelegate.buildSearchUrl tests for empty _sortKeys handling (OpenIdentityPlatform#186) Cover the normal case, the leading-undefined fallback to the first non-empty property, and full omission of _sortKeys when no property is usable.
maximthomas
approved these changes
Jun 4, 2026
…mple search (OpenIdentityPlatform#186) Build the sample-search URL via a new buildSearchUrl helper that derives _sortKeys from the first non-empty property, omits the parameter entirely when no usable property exists, and skips _sortKeys for system/... resources whose connectors (e.g. the CSV connector) may not support server-side sorting. This prevents both the empty "_sortKeys=" and the unsupported-sort HTTP 500 errors.
…yPlatform#186) MappingUtils.setupSampleSearch passed the search results to the selectize `load` callback wrapped in an extra array (callback([response])). Since SearchDelegate.searchResults already resolves to a flat array of records, this produced a nested [[record, ...]] structure: selectize treated the inner array as a single option, _.pick() returned an empty object, and the dropdown showed one empty, unselectable entry instead of the matching record. As a result the getting-started "Sample Source 'Sanchez'" flow never displayed the "Jane Sanchez" option. Pass the results through as a flat array (callback(response)) and guard the success branch with response.length so an empty result set falls back to the no-results callback. Add MappingUtilsTest coverage for setupSampleSearch: - the selectize `load` callback receives a flat array of records; - valueField/searchField skip properties without a `source`.
…latform#186) The admin UI maps underscore to lodash 3.10.1, where _.first(array, n) ignores n and returns only the first element. Building the representative property list via _.chain().pluck("source").filter().first(n).value() therefore yielded the single string "email" instead of an array; it was then spread into characters, producing a malformed _queryFilter (e sw "..." or (m sw "..." ...)) that the system endpoint rejected with HTTP 400, leaving the sample-source dropdown empty. Build the representative props with native Array filter().slice(0, n) in AttributesGridView, SingleRecordReconciliationView and DataAssociationManagementView. Verified end-to-end against a live getting-started instance: all getting-started Playwright tests pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #186
Summary
Using Sample Source (Properties tab) or Single Record Reconciliation
(Behaviors tab) returned an "Internal Error" with nothing meaningful in the logs
whenever the first property of a mapping had no
source(e.g. atransform-only / target-only property).
Root cause
The admin UI built the autocomplete property list with
_.pluck(mapping.properties, "source")and took the first N elements withoutchecking whether they were defined. When the first property had no
source, aleading
undefinedended up in the list and was passed down toSearchDelegate.searchResults, which injectedprops[0]directly into the URL:The empty
_sortKeys=is rejected by the CREST/IDM backend, producing anHTTP 500 that surfaced only as a generic "Internal Error" (the failure was
logged via
console.erroronly).Changes
Defensive fix (lowest level)
SearchDelegate.js— extracted URL construction into a testablebuildSearchUrl(...)._sortKeysis now derived from the first non-emptyproperty; if no usable property exists, the
_sortKeysparameter is omittedentirely. This guarantees an empty
_sortKeys=can never be emitted again,even if a "leaky" property array is passed in the future.
In addition,
_sortKeysis omitted forsystem/...resources, becausemany connectors (e.g. the CSV connector used by the getting-started sample)
do not support server-side sorting and would otherwise fail the whole sample
query with an HTTP 500. Sample searches are capped at a few results, so the
sort order is not required.
Source fixes (UI views)
SingleRecordReconciliationView.js—setupSearchnow filters out emptysourcevalues before slicing the representative props.AttributesGridView.js— same filtering for the dynamic Sample Source.DataAssociationManagementView.js— same filtering for bothsourceandtargetrepresentative props.MappingUtils.js—setupSampleSearchcompacts the property list andguards
valueField/searchFieldagainstundefined.Tests
SearchDelegateTest.js— added QUnit tests forbuildSearchUrl:_sortKeysset to the first property in the normal case;undefinedno longer produces an empty_sortKeys=and falls backto the first non-empty property (the Suggestion for modification on how the sortKeys are selected in the sample queries in Mappings #186 scenario);
_sortKeysomitted entirely when no property is usable;_sortKeysomitted forsystem/...resources (CSV/connector sources).MappingUtilsTest.js— added QUnit tests forsetupSampleSearch:loadcallback receives a flat array of records;valueField/searchFieldskip properties without asource.Affected files
openidm-ui/openidm-ui-common/.../delegates/SearchDelegate.jsbuildSearchUrlhelper; never emit empty_sortKeys=; skip_sortKeysforsystem/...resourcesopenidm-ui/openidm-ui-admin/.../mapping/behaviors/SingleRecordReconciliationView.jssourceinsetupSearchopenidm-ui/openidm-ui-admin/.../mapping/properties/AttributesGridView.jssourcefor Sample Sourceopenidm-ui/openidm-ui-admin/.../mapping/association/DataAssociationManagementView.jssource/targetopenidm-ui/openidm-ui-admin/.../mapping/util/MappingUtils.jsvalueField/searchField; pass flat array to selectizeloadopenidm-ui/openidm-ui-common/.../test/.../SearchDelegateTest.jsbuildSearchUrlopenidm-ui/openidm-ui-admin/.../test/.../MappingUtilsTest.jssetupSampleSearchHow to test
source(transform/target-only).no "Internal Error".
search works as expected.
Search Delegate Testspass, including the newbuildSearchUrlcases.(
OPENIDM_SAMPLE=samples/getting-started) — the Sample Source 'Sanchez'test passes: typing
Sanchezshows the Jane Sanchez dropdown option andselecting it populates the preview (the
system/hr/accountCSV connector nolonger fails on
_sortKeys).