Skip to content

ITAB_ILL_COMPONENT

A component access used a field name or index that does not exist in the table's line type.

The program tried to read or assign a component of an internal table row using a name or position that is not part of the row structure.

Symptom

ST22 shows:

Runtime Errors         ITAB_ILL_COMPONENT
Short text             Illegal component access in internal table operation.

The dump line is typically a dynamic component access using ASSIGN COMPONENT.

Cause

Common triggers:

  • ASSIGN COMPONENT lv_fieldname OF STRUCTURE ls_row TO <fs> where lv_fieldname does not exist in the structure.
  • Dynamic field access using a field name that was spelled wrong or came from user input.
  • A structure was changed (field removed/renamed) but the calling code was not updated.
  • Using a numeric component index that is out of range.

Reproduce

TYPES: BEGIN OF ty_item,
         matnr TYPE matnr,
         menge TYPE menge_d,
       END OF ty_item.

DATA: ls_item      TYPE ty_item,
      lv_fieldname TYPE string VALUE 'WERKS'.   " does not exist in ty_item

FIELD-SYMBOLS: <fs> TYPE any.

ASSIGN COMPONENT lv_fieldname OF STRUCTURE ls_item TO <fs>.
" <fs> is not assigned after this — accessing it would cause GETWA_NOT_ASSIGNED
" On strict kernels, ITAB_ILL_COMPONENT fires on the ASSIGN itself
IF <fs> IS ASSIGNED.
  WRITE <fs>.   " only reached if component was found
ENDIF.

Numeric index variant (always dumps):

ASSIGN COMPONENT 99 OF STRUCTURE ls_item TO <fs>.   " only 2 components exist — dump

Fix

All fix examples use the same data declarations as the reproduce example above for easy copy-paste.

TYPES: BEGIN OF ty_item,
         matnr TYPE matnr,
         menge TYPE menge_d,
       END OF ty_item.

DATA: ls_item      TYPE ty_item,
      lv_fieldname TYPE string VALUE 'MATNR',
      lv_value     TYPE string.

FIELD-SYMBOLS: <fs> TYPE any.

ASSIGN COMPONENT lv_fieldname OF STRUCTURE ls_item TO <fs>.

IF <fs> IS ASSIGNED.
  lv_value = <fs>.
  WRITE lv_value.
ELSE.
  " field does not exist in the structure
  MESSAGE |Field { lv_fieldname } not found in structure| TYPE 'W'.
ENDIF.
TYPES: BEGIN OF ty_item,
         matnr TYPE matnr,
         menge TYPE menge_d,
       END OF ty_item.

DATA: ls_item      TYPE ty_item,
      lv_fieldname TYPE string VALUE 'MATNR'.

FIELD-SYMBOLS: <fs> TYPE any.

DATA(lo_descr) = CAST cl_abap_structdescr(
                   cl_abap_typedescr=>describe_by_data( ls_item ) ).

IF line_exists( lo_descr->components[ name = to_upper( lv_fieldname ) ] ).
  ASSIGN COMPONENT lv_fieldname OF STRUCTURE ls_item TO <fs>.
  IF <fs> IS ASSIGNED.
    WRITE <fs>.
  ENDIF.
ELSE.
  MESSAGE |Field { lv_fieldname } does not exist| TYPE 'W'.
ENDIF.
TYPES: BEGIN OF ty_item,
         matnr TYPE matnr,
         menge TYPE menge_d,
       END OF ty_item.

DATA ls_item TYPE ty_item.
ls_item-matnr = '000000000000000001'.
ls_item-menge = 10.

" Instead of dynamic ASSIGN COMPONENT, access directly — no runtime risk
WRITE: / ls_item-matnr, ls_item-menge.

Prevention

  • Always check IS ASSIGNED after every ASSIGN COMPONENT — never assume the field name is valid.
  • Validate dynamic field names against the structure's type descriptor (CL_ABAP_STRUCTDESCR) before use.
  • Use consistent variable names across reproduce and fix examples so code can be copied and extended without renaming.
  • When a structure changes, search for all ASSIGN COMPONENT usages with the old field name (SE80 where-used list).

See also

Comments