I took the table structure Scorby had suggested and then we ran the following. There was a trigger on the original table and I disabled the trigger first and was able to do the insert. That pointed us in the direction we took. The following is the code to create a trigger on the X and Y tables and then the different test cases.

Looks like this is being caused by a before-row-level trigger
wherein the :new value appears on both sides of an assignment function.

It seems to be only a problem for insert, not update

Other things to try: after-row trigger, delete statements, ...

-----------------------------------------------------------------------------
-- TEST TRIGGER
-----------------------------------------------------------------------------
CREATE OR REPLACE TRIGGER Y_BIUR
BEFORE INSERT OR UPDATE ON Y
FOR EACH ROW

DECLARE
ln_mynum NUMBER := 0;

BEGIN

--test case 1 reference to :new value FAIL INSERT, PASS UPDATE
:new.A := :new.A ;

--test case 2 reference to :new value FAIL INSERT, PASS UPDATE
-- :new.A := :new.A + 1 ;

--test case 3 reference to :new value PASS INSERT, PASS UPDATE
--ln_mynum := :new.A ;

--test case 4 reference to :new value PASS INSERT, PASS UPDATE
--:new.A := 1;

END;

-------------------------------------------------------------------------
-- TEST DML
-------------------------------------------------------------------------
-- insert test
INSERT INTO y (ID, a, b)
VALUES (6, (SELECT a FROM y WHERE ID =3), SYSDATE);

-- update test
UPDATE y
SET ID = 5, a = (SELECT a FROM y WHERE ID = 3), b = SYSDATE
WHERE ID = 5;