The most cryptic OBIEE error explained. Multi-fact join rules, error codes E4T4O7MK and OPR4ONWY, and four copy-paste fixes that actually work.
The pCriteria != 0 assertion is an internal Oracle BI Server guard. pCriteria is a bitmask that tracks which filter conditions are "pushed down" to each physical data source for a given query. The assertion fires when the BI Server cannot assign at least one filter criterion to a particular Logical Table Source (LTS) — meaning it would have to cross-query two unrelated fact tables with no valid join path between them.
In plain English: you asked OBIEE to combine columns from two different fact tables that don't share a common dimension key in this query. OBIEE refuses rather than returning a Cartesian product.
Common trigger: Dragging columns from Workforce Management and Payroll subject areas into the same OTBI analysis. These map to different fact tables (WFM_FACT_* vs PAY_FACT_*) with no direct join key available at query time.
The error surfaces in different wrappers depending on whether you hit it through Answers, OTBI, or a raw JDBC/ODBC connection. The internal assertion always reads the same:
| Error Code | Meaning |
|---|---|
OPR4ONWY | ODBC driver wrapper — the outer container for the real error |
U9IM8TAC | Internal BI Server exception propagation |
OI2DL65P | Query state serialization failure |
nQSError: 27002 | Syntax or state error in the generated Logical SQL |
E4T4O7MK | The specific assertion: pCriteria != 0 failed for an LTS |
The nQSError: 27002 in the stack trace does not mean you have a syntax error in your hand-written SQL. It refers to an internal state that OBIEE itself generated. Do not waste time hunting for typos — fix the join structure instead.
OBIEE's Logical SQL is translated to physical SQL by the BI Server in a two-phase process: first, it resolves which Logical Table Sources map to each column; second, it builds join paths between them. The pCriteria bitmask is the bookkeeping structure for step two.
When you select columns that map to two different fact LTS tables, the BI Server needs a shared dimension key to join them. If no such key is available in the current query context (because you didn't include the bridging dimension column, or because the RPD doesn't define the join), pCriteria stays at 0 for one of the LTS entries and the assertion fires.
| Columns Mixed | Fact Tables | Missing Link |
|---|---|---|
| Headcount + Payroll run results | WFM_HEADCOUNT_FACT + PAY_RUN_RESULT_VALUES | Assignment ID at pay period grain |
| Absence balance + Payroll element | ANC_BALANCE_FACT + PAY_ELEMENT_ENTRIES_F | Person ID with matching date grain |
| Compensation + Time & Labor | CMP_SALARY_FACT + HXT_TIMECARD_SUMMARY | No join defined in delivered RPD |
The cleanest fix is to scope your analysis to a single subject area and single fact. Ask: what is the primary question this report answers? Strip columns from the secondary fact entirely.
Works every time. If you need payroll data, use the Payroll subject area exclusively. If you need headcount, use Workforce Management. Two separate reports are better than one broken combined report.
If both fact tables are joinable — they just lack the link in your current query — adding the shared dimension column to your criteria forces OBIEE to build the join path and resolves the assertion.
For most HCM + Payroll crosses, the bridge is Assignment ID:
-- Before fix: mixing headcount columns with pay run columns -- This causes pCriteria != 0 because no join key is present SELECT "Workforce Management - Workforce Trend"."Department"."Department Name", "Workforce Management - Workforce Trend"."Headcount"."Headcount", "Payroll - Payroll Run Results"."Element"."Element Name", "Payroll - Payroll Run Results"."Run Result Values"."Pay Value" FROM "Workforce Management - Workforce Trend" -- After fix: add the bridging assignment column SELECT "Workforce Management - Workforce Trend"."Worker"."Assignment Number", -- bridge key "Workforce Management - Workforce Trend"."Department"."Department Name", "Payroll - Payroll Run Results"."Run Result Values"."Pay Value" FROM "Workforce Management - Workforce Trend"
In Oracle OTBI (cloud), the bridge column must be from a conformed dimension — one that exists in both subject areas with the same grain. Person Number and Assignment Number are the most reliable conforming keys across HCM subject areas.
When the two fact tables truly don't share a join path (no conforming key exists in the RPD), separate them into two individual analyses and union or link them at the presentation layer.
In OTBI Answers, create two analyses and use Combined Results (the Set Operations tab). In BI Publisher, create two separate data sets in the data model and join them using a correlated lookup element on Person Number.
The Union approach only works if both queries return the same grain (same number and type of columns). If one returns one row per department and the other returns one row per element, you need a BI Publisher data model join instead.
For advanced users with physical SQL access to the underlying DB, the EVALUATE function lets you push a subquery directly to the database, bypassing the BI Server's join logic entirely. Use this when you genuinely need combined data and can't change the RPD.
-- EVALUATE pushes a SQL fragment to the DB engine -- The BI Server treats it as an opaque scalar — no pCriteria check SELECT "Workforce Management - Workforce Trend"."Department"."Department Name", "Workforce Management - Workforce Trend"."Headcount"."Headcount", EVALUATE('(SELECT SUM(prv.result_value) FROM pay_run_result_values prv JOIN pay_assignment_actions paa ON paa.assignment_action_id = prv.assignment_action_id WHERE paa.assignment_id = %1 AND TRUNC(SYSDATE) BETWEEN paa.effective_start_date AND paa.effective_end_date)' AS DOUBLE, "Workforce Management - Workforce Trend"."Worker"."Assignment Id") AS pay_value FROM "Workforce Management - Workforce Trend"
EVALUATE risks: (1) Bypasses BI Server caching. (2) Runs N+1 queries — one scalar subquery per row. (3) Requires the physical SQL to use correct table names, which differ between on-prem OBIEE and Oracle Cloud. Test with row limits before production use.
In Oracle Fusion Cloud (OTBI), you don't have direct RPD access, so Fixes 1–3 are the only options. The EVALUATE workaround requires your Cloud tenant to have EVALUATE enabled — Oracle disables it by default in SaaS because it allows arbitrary SQL execution against the HCM schema.
Cloud-specific triggers that look like pCriteria errors but have different fixes:
pCriteria. Delete the affected column and re-add it from the current subject area tree.Run through this in order before rebuilding the report from scratch:
Search 14,950 Oracle HCM tables and trace every column back to its physical source — useful when you're not sure which fact table a column belongs to.
Search HCM Tables →