2015 m. vasario 12 d., ketvirtadienis

Valid Time State Key Error after Upgrading or Updating

Hello AX World,

Have you ever had a compilation error “Table does not contain a valid time state key. A unique index needs to be marked as a valid time state key.” and could not realize where it came from? I had… many times and I did not have a clue until one day.

Such errors look strange as they show up on completely standard objects.

I have noticed that they were showing up after upgrades or updates (CUs, hot fixes etc.). That gave me a hint. I know that during an upgrade there are upgrade scripts running to enable or disable certain indexes. So I assumed that these scripts are not behaving well enough. I tried to dig it up, to find scripts that were failing and I have found the problem.


The the index is disabled using indexAllowDup method, then properties AlternateKey and ValidTimeStateKey are reset to default value No.

ReleaseUpdateDB::indexAllowDup(new DictIndex(tableNum(TableName),
indexNum(TableName, DateEffectiveIndex)));

The error starts to show up then indexes are not enabled correctly using method indexAllowNoDup:

ReleaseUpdateDB::indexAllowNoDup(new DictIndex(tableNum(TableName),
indexNum(TableName, DateEffectiveIndex)));

AlternateKey and ValidTimeStateKey properties are not set using the code and then you start getting compilation error mentioned above.

You should use the method indexAllowNoDupAndDateEffective instead:

ReleaseUpdateDB::indexAllowNoDupAndDateEffective(new DictIndex(tableNum(TableName),
indexNum(TableName, DateEffectiveIndex)), ValidTimeStateMode::Gap or NoGap);

Sometimes you can see the following code, but that is implemented in indexAllowNoDupAndDateEffective method:

DictIndex dictIndex = new DictIndex(tableNum(TableName),
        indexNum(TableName, DateEffectiveIndex));
    dictIndex.modify(true, false, true);
    dictIndex.setAlternateKey(true, true);
    dictIndex.setValidTimeStateKey(true, ValidTimeStateMode::Gap or NoGap, true);
    appl.dbSynchronize(dictIndex.tableid(), false);

Recent experience

I have got 3 errors after upgrading from AX 2009 to AX 2012 R3. In earlier versions I had experienced even more…

Tables that there failing:
  1. EximDBKValues_IN (Index: TariffCodeIdx)
  2. EximDEPBScheduleTable_IN (Index: ProductGroupTableRecIdx)
  3. PdsRebateAgreement (Index: SeqIdx)
EximDBKValues_IN table had 4 (!) methods disabling/enabling the same index. The problem was that the incorrect script have been executed the last thus "enabled" the index incorrectly.

  1. ReleaseUpdateDB60_Cust. allowDupEximDBKValues_IN
  2. ReleaseUpdateDB60_Cust. allowNoDupEximDBKValues_IN
  3. ReleaseUpdateDB60_Ledger.allowDupEximDBKValues_INTariffCodeIdx
  4. ReleaseUpdateDB60_Ledger.allowNoDupEximDBKValues_INTariffCodeIdx
EximDEPBScheduleTable_IN table had 2 methods as expected but index enabling was incorrect.
  1. ReleaseUpdateDB60_Ledger.allowDupEximDEPBScheduleTable_INProductG
  2. ReleaseUpdateDB60_Ledger.allowNoDupEximDEPBScheduleTable_INProduc
public void allowNoDupEximDEPBScheduleTable_INProduc()
    ReleaseUpdateDB::indexAllowNoDup(new DictIndex(tableNum(EximDEPBScheduleTable_IN),
        indexNum(EximDEPBScheduleTable_IN, ProductGroupTableRecIdx)));

PdsRebateAgreement table had 2 methods, the same as EximDEPBScheduleTable_IN and enabling index was incorrect.
  1. PmfReleaseUpdateDB60_Pds.allowDupPdsRebateAgreementSeqIdx
  2. PmfReleaseUpdateDB60_Pds.allowNoDupPdsRebateAgreementSeqIdx
public void allowNoDupPdsRebateAgreementSeqIdx()
    ReleaseUpdateDB::indexAllowNoDup(new DictIndex(tableNum(PdsRebateAgreement),
        indexNum(PdsRebateAgreement, PdsRebateAgreementSeqIdx)));

I hope that helps you to save some valuable time to spend on more interesting things.