---
title: "ADR-199: A copy is a hidden draft, and a page is copied without its branch"
manual: "LLM Foundation"
version: "0.44"
permalink: "https://docs.typo3.org/permalink/netresearch/nr-llm:adr-199@0.44"
source: "Adr/Adr199ACopyIsAHiddenDraftWithoutItsBranch.rst"
rendered: "2026-11-12T17:35:48+00:00"
---

# ADR-199: A copy is a hidden draft, and a page is copied without its branch {#adr-199}

-   *Status:* Accepted
-   *Date:* 2026-09-23
-   *Amends:* [ADR-180](https://docs.typo3.org/permalink/netresearch/nr-llm:adr-180@0.44) (its one-record rule, for the rows core's copy command brings along)
-   *Authors:* Netresearch DTT GmbH

## Context {#adr-199-context}

[ADR-180](https://docs.typo3.org/permalink/netresearch/nr-llm:adr-180@0.44) held that one call creates one record, so an approver
judges one thing. `copy_record` ([ADR-198](https://docs.typo3.org/permalink/netresearch/nr-llm:adr-198@0.44)) runs core's copy
command, and that command is more than one row: it copies the translations of a
default-language record — since 13.4.25 only where the target site carries their
language — the file references and inline children of every copied row, and for
a page the records stored on it — for a non-admin, those of the tables in
`tables_modify`. It can also copy a page's whole branch, and it hides only
what it copies FIRST: `hideAtCopy` applies to the top record, unless the
user's `neverHideAtCopy` preference switches even that off.

## Decision {#adr-199-decision}

1.  **The copy is core's copy.** The rows it brings along are the ones the
    page module's copy would bring; the tool does not pick among them, and
    the approval card counts them — the translations, and for a page the
    content elements on it.
1.  **The copy is hidden, whatever core and the user's preferences say — and
    so is every translation copied with it.** The hidden column is set in the
    paste `update` of the same command, which reaches the copy only; the
    copied translations get it from core's `hideAtCopy`, which the user
    preference `neverHideAtCopy` (pinned to 0 for the call) and page TSconfig
    `disableHideAtCopy` switch off, so the tool sets it on every copied
    translation that came out visible, in a second write of the same call.
    Readback checks the main record's `pid`, `hidden` and `colPos` and
    returned translations. A failing checked record is deleted again with its
    translations, and the answer says whether that worked. Between the copy
    and the second write a copied translation can be visible for the duration
    of one request. This workflow does not guarantee invisibility at every
    intermediate instant. Inline children, page content and other core-copied
    records are not all read back; the hidden main copy may survive a core
    complaint about those records, with a warning about incomplete copying.
1.  **A page is copied without its subpages, always.** Core would hide only
    the top page of a copied branch and leave every copied subpage as visible
    as its original — reachable under a hidden parent, with a new URL. The
    depth is pinned to 0 for the call: TYPO3 14 reads it from the acting
    user's `copyLevels` preference, which the tool sets for the call and
    puts back without saving it; TYPO3 13 reads the DataHandler's
    `copyTree`, which is 0 unless set.
1.  **Translations follow core.** A translation is never copied by itself.
    In TYPO3 14 and 13.4.25 or later no translation is copied outside a
    site; inside one, a translation is copied where the site has its
    language (for an element, where the target page is translated into it),
    and core complaints are reported. A complaint does not always remove a
    valid hidden main copy; rollback follows the explicit readback checks
    (`DataHandler::copyL10nOverlayRecords()`). Before 13.4.25 core asks
    no site: it copies every page translation, and drops an element
    translation the target page is not translated into without an error. The
    tool adds no rule of its own; the card states the running core's rule,
    and the answer counts the translations that were placed. A page
    translation is no target.

## Consequences {#adr-199-consequences}

✓ The one-record rule becomes "one record the approver named, and what
core copies with it, counted on the card" — the rule a human applies in the
page module.

✕ A branch is copied page by page, one approval each. That is slower than
core's recursive copy and is the price of every copied page being hidden.

## Revisit when {#adr-199-revisit}

A branch copy is wanted often enough that one approval per page is a
burden; the rule then needs every copied page hidden in the same command,
which core's copy does not offer.
