Skip to content

SYNTAX_ERROR

Dynamically generated ABAP code contained a syntax error detected at runtime.

This is a runtime syntax error — distinct from the compile-time errors caught by SE38's syntax check. The error occurs when ABAP generates or compiles code dynamically and the generated source contains invalid syntax.

Symptom

ST22 shows:

Runtime Errors         SYNTAX_ERROR
Exception              CX_SY_SYNTAX_ERROR (in newer kernels)
Short text             Syntax error in dynamically generated program.

The dump includes a "Generated source" or "Dynamic program" section showing the code that failed to compile.

Cause

Dynamic ABAP constructs that generate code at runtime:

Statement What it generates
GENERATE SUBROUTINE POOL Builds a temporary program from string lines
INSERT REPORT Writes a new program source to the repository
CREATE DATA ... TYPE (lv_type_name) Type resolved at runtime

Common triggers:

  • A string built to pass to GENERATE SUBROUTINE POOL contains a typo, missing period, or unclosed string literal.
  • A dynamic type name (TYPE (lv_type)) contains a name that doesn't exist in the DDIC.

Reproduce

The reproduce example uses GENERATE SUBROUTINE POOL with intentionally broken source code. The error message appears — no actual dump is triggered if you check sy-subrc:

DATA lt_source TYPE STANDARD TABLE OF string.
DATA lv_prog   TYPE string.

APPEND 'REPORT ztemp.'  TO lt_source.
APPEND 'FORM test.'     TO lt_source.
APPEND '  DATA lv_x TYPE' TO lt_source.   " missing type name — syntax error
APPEND 'ENDFORM.'       TO lt_source.

GENERATE SUBROUTINE POOL lt_source NAME lv_prog
  MESSAGE DATA(lv_msg)
  SHORTDUMP-ID DATA(lv_dump_id).

IF sy-subrc <> 0.
  " lv_msg contains the description of the syntax error
  MESSAGE lv_msg TYPE 'E'.   " e.g. "Field '.' is unknown."
ENDIF.

The actual dump fires only if you skip the sy-subrc check and call PERFORM ... IN PROGRAM (lv_prog) when generation failed — because the program doesn't exist.

Fix

This is the same example as reproduce, but now we fix the source code so generation succeeds:

DATA lt_source TYPE STANDARD TABLE OF string.
DATA lv_prog   TYPE string.

" Fixed source — complete TYPE declaration
APPEND 'REPORT ztemp.'       TO lt_source.
APPEND 'FORM test.'          TO lt_source.
APPEND '  DATA lv_x TYPE i.' TO lt_source.   " now valid
APPEND 'ENDFORM.'            TO lt_source.

GENERATE SUBROUTINE POOL lt_source NAME lv_prog
  MESSAGE DATA(lv_msg)
  SHORTDUMP-ID DATA(lv_dump_id).

IF sy-subrc <> 0.
  " Generation failed — log the message, do NOT call PERFORM
  MESSAGE |Dynamic program syntax error: { lv_msg }| TYPE 'E'.
  RETURN.
ENDIF.

" Only call PERFORM if generation succeeded (sy-subrc = 0)
PERFORM test IN PROGRAM (lv_prog).

If your reproduce error comes from an invalid dynamic type name:

REPORT z_syntax_error_fix2.

START-OF-SELECTION.

  DATA: lv_type_name TYPE string VALUE 'BAPI_RETURN',
        lo_data      TYPE REF TO data,
        lo_type      TYPE REF TO cl_abap_typedescr.

  " describe_by_name raises classical exception TYPE_NOT_FOUND (not OO).
  " Use CALL METHOD with EXCEPTIONS — do NOT use TRY/CATCH here.
  CALL METHOD cl_abap_typedescr=>describe_by_name
    EXPORTING
      p_name      = lv_type_name
    RECEIVING
      p_descr_ref = lo_type
    EXCEPTIONS
      type_not_found = 1
      OTHERS         = 2.

  IF sy-subrc <> 0.
    MESSAGE |Type { lv_type_name } does not exist in DDIC| TYPE 'E'.
    RETURN.
  ENDIF.

  " Type confirmed — safe to use in CREATE DATA
  CREATE DATA lo_data TYPE (lv_type_name).
  WRITE: / 'Type exists:', lo_type->get_relative_name( ).

Dynamic code generation is a last resort

GENERATE SUBROUTINE POOL is powerful but fragile. Prefer static code, polymorphism, or configuration tables over dynamically assembled source code. Every string you assemble is a potential syntax error.

Prevention

  • Always check sy-subrc after GENERATE SUBROUTINE POOL before calling the generated program.
  • Log lv_msg when generation fails — it contains the exact syntax error location.
  • Validate all dynamic type names with CL_ABAP_TYPEDESCR=>DESCRIBE_BY_NAME before use.

See also

  • LOAD_PROGRAM_NOT_FOUND — related dynamic program dump
  • Transaction ST22 — ABAP runtime error analysis (includes generated source in dump)

Comments