Pre-Hooks for Pricing? The Key to Consistent UI and API Outcomes
Sometimes the strongest architecture lessons come from a mismatch that should not exist.
Pre-Hooks for Pricing? The Key to Consistent UI and API Outcomes

Sometimes the strongest architecture lessons come from a mismatch that should not exist.
A quote can price successfully in Salesforce UI, while the same shape of quote fails when created and priced through API.
A representative API call returned:
isSuccess: falseDUPLICATE_VALUE_FOUND_IN_LOOKUP- Message: Enable Output Resolution when the lookup table has multiple outcomes
That creates a very specific signal:
- UI create + price: works
- API create + price: fails
This post explains the key learning behind that signal: how pricing context is prepared, why UI and API can diverge, and what to put in place so both paths behave consistently.
Why This Learning Matters
The practical lesson is simple:
The issue is often not whether values exist in the transaction, but where those values exist at pricing time.
- Selected values existed in attribute rows (child collection).
- Pricing lookup steps read line-level scalar values (parent line node).
- For API calls, those scalar values stayed
null, so lookup keys became partial. - Partial keys matched multiple decision-table rows, producing
DUPLICATE_VALUE_FOUND_IN_LOOKUP.
The resolution pattern is to ensure pre-pricing logic converts attribute rows into line-level scalar values, including picklist-driven values.
The Core Context Model (in simple language)
In Revenue Cloud context, each quote line has:
- A parent line node (one row per line)
- A child attribute collection (many rows per line)
Pricing procedures and decision tables usually read values from the parent line node (single-value fields/tags).
So even if the user has selected attributes, pricing can still see null unless you:
- hydrate a scalar directly from a line field, or
- flatten child attribute values into parent line scalars before pricing
This parent-vs-child difference is the key design point.
Triage Findings
The first validation pass covered decision-table data and payload content. Both looked correct at first.
Runtime logs then showed the real issue:
- API call did invoke pricing and pre-pricing logic.
- Attribute rows were present in context.
- But line-level values needed by lookup steps were still
null.
The important detail:
- Text attributes were available through a text value slot.
- Picklist attributes were available through picklist Ids.
- The flatten logic in use relied on the text slot only for those attributes.
So for picklist-driven values, line-level scalars stayed null.
That caused partial lookup keys and duplicate matches.
Why UI Worked but API Failed
The difference came from execution path, not business data.
- In UI-driven flows, context preparation/configuration path populated values in a way pricing consumed correctly.
- In API-driven create-and-price flow, with configuration path settings used for that request, the required line-level scalar values were not fully prepared before lookup evaluation.
So the same functional quote could behave differently depending on how it was created/priced.
This is why API-path testing is mandatory for pricing logic.
Resolution Approach
The same architecture was retained, with a targeted fix in pre-pricing value preparation:
1) Read both value paths
- Read text value when present.
- If text is empty, resolve from picklist Id to picklist value text.
2) Add transaction-level cache
- Cache
PicklistId -> PicklistValue. - Query only uncached ids.
- Avoid repeated queries when the same hook is invoked multiple times in one transaction.
3) Keep it bulk-safe
- No SOQL inside row loops.
- Collect all needed ids first, then query once.
4) Keep logging useful but low-noise
- Keep diagnostics at
FINElevel. - Preserve observability without flooding logs.
Validation Results
Before:
- Lookup input values on line context were
nullfor required keys. - API response had
DUPLICATE_VALUE_FOUND_IN_LOOKUP.
After:
- Required line context values were populated.
- API response returned
isSuccess: true. - Duplicate lookup errors disappeared.
Most important takeaway: Validate runtime context values, not just payload shape and final response.
Important Clarification: Pre-Hook Is Not Always Required
Not every Revenue Cloud pricing implementation needs an Apex pre-hook.
You should use one only when your implementation requires pre-pricing context shaping, such as:
- flattening child attribute rows into line-level scalars
- deriving values not directly hydrated from line fields
- normalizing values before decision-table lookups
If standard hydration and configuration flow already produce correct line-level inputs, a pre-hook may be unnecessary.
Reusable Pattern (When You Do Need a Pre-Hook)
- Read the minimum context rows needed.
- Transform child attribute rows into parent line scalar values.
- Resolve picklist ids to text values where needed.
- Cache repeated id lookups per transaction.
- Write updates in one bulk context update operation.
- Verify in API path, not only UI path.
Practical Setup Checklist
- Use pre-hook only if your use case needs it.
- If used, place it before pricing section in the procedure plan.
- Required pricing inputs exist as line-level scalar tags.
- Attribute-to-tag mapping is externalized (custom metadata/custom config).
- Pre-hook supports both text and picklist attributes.
- Decision-table input keys are non-null after pre-hook.
- Integration test must cover API create-and-price path with representative payload.
Closing Thought
This duplicate lookup error was not random and not just a bad table.
It was a context-preparation gap in API create-and-price flow.
Once the correct line-level values were prepared before pricing, the issue was resolved and the same API flow succeeded.
If your team sees works in UI, fails in API pricing behavior, compare runtime context values first. That one step can save days of trial-and-error.
메타데이터
- post_id
- 8cdab12cdcab
- slug
- pre-hooks-for-pricing-the-key-to-consistent-ui-and-api-outcomes-8cdab12cdcab
- url
- https://medium.com/@arohitu/pre-hooks-for-pricing-the-key-to-consistent-ui-and-api-outcomes-8cdab12cdcab
- canonical_url
- https://medium.com/@arohitu/pre-hooks-for-pricing-the-key-to-consistent-ui-and-api-outcomes-8cdab12cdcab
- author_url
- https://medium.com/@arohitu
- status
- ok
- fetched_at
- 2026-06-12 18:14:10