For a RELATIVE file in RANDOM or DYNAMIC access, DELETE and REWRITE of a record number whose slot is empty, because the record was deleted or never written, give I-O status 00 and take the NOT INVALID KEY branch, and the REWRITE stores no record; READ of the same key gives 23.
reldel.cob (attached) writes record 1, then in I-O mode deletes it twice, rewrites it and reads it:
IDENTIFICATION DIVISION.
PROGRAM-ID. RELDEL.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT F ASSIGN TO "reldel.dat"
ORGANIZATION IS RELATIVE
ACCESS MODE IS RANDOM
RELATIVE KEY IS RK
FILE STATUS IS FS.
DATA DIVISION.
FILE SECTION.
FD F.
01 R PIC X(4).
WORKING-STORAGE SECTION.
01 RK PIC 9(3) VALUE 0.
01 FS PIC XX VALUE SPACES.
PROCEDURE DIVISION.
OPEN OUTPUT F
MOVE 1 TO RK
MOVE "AAAA" TO R
WRITE R
CLOSE F
OPEN I-O F
DELETE F RECORD
DISPLAY "DELETE 1 " FS
DELETE F RECORD
DISPLAY "DELETE 2 " FS
MOVE "BBBB" TO R
REWRITE R
DISPLAY "REWRITE " FS
READ F
DISPLAY "READ " FS
CLOSE F
STOP RUN.
cobc -std=cobol2014 -fformat=free -x reldel.cob && ./reldel
3.2.0 and 3.3-dev r5751 both print
DELETE 1 00
DELETE 2 00
REWRITE 00
READ 23
and the same with -std=cobol2002, -std=cobol85 and the default dialect. delhole.cob, attached, shows the same for a slot that was never written, and deltwice.cob shows that the INVALID KEY phrase is not taken (SECOND DELETE OK 00).
The second DELETE and the REWRITE give status 23, run their INVALID KEY phrase and change nothing in the file. DELETE general rule 4 (ISO/IEC 1989:2023 14.9.10.4) and REWRITE general rule 21 (14.9.35.4) make this the invalid key condition, and then, by 9.1.14, "execution of the input-output statement that recognized the condition is unsuccessful and the file is not affected". The same rules are in the 2002 final draft and the 2014 FCD (REWRITE rule 20 there).
In libcob/fileio.c, relative_read treats a record-size word of 0 as an empty slot, but relative_rewrite (random and dynamic access) and relative_delete return 23 only when the size word cannot be read, past the end of the file.
The attached n10-relative-delete-rewrite.patch (against 3.3-dev r5751) makes relative_delete and relative_rewrite return COB_STATUS_23_KEY_NOT_EXISTS before writing anything when the size word for the key is 0. Both leave the file offset where it was before the patch, so later READ NEXT and READ PREVIOUS return the same records. It adds the testsuite case "DELETE / REWRITE of a missing RELATIVE record" to run_file.at, with ChangeLog entries. make check: 1373 expected, 9 skipped, 0 failed (1372 unpatched); the new test fails without the patch.
Other behavior changes:
libcob: error: record key does not exist (status = 23), as it does today for any other status 23.bugs #1281: the run unit stops on a status 10 or 2x when the file has no FILE STATUS clause.
GnuCOBOL 3.2.0 (Ubuntu gnucobol3 3.2-4build1) and 3.3-dev r5751 (CI snapshot 3.3-dev.138 of 2026-10-29), x86_64 Linux, both run 2026-11-04, default file handler.