diff --git a/skills/uipath-coded-apps/references/sdk/data-fabric.md b/skills/uipath-coded-apps/references/sdk/data-fabric.md
index e4003b1e31..98f0291464 100644
--- a/skills/uipath-coded-apps/references/sdk/data-fabric.md
+++ b/skills/uipath-coded-apps/references/sdk/data-fabric.md
@@ -18,7 +18,7 @@ Data Fabric does NOT behave like a typical RDBMS. These server behaviors are inv
6. **No `IsNull` filter operator.** The server can't ask "where field is null" (`QueryFilterOperator` has no such member). Filter client-side after fetching, or design with explicit non-null sentinels.
7. **Aggregates require server-side `aggregates` + `groupBy`.** Don't fetch raw rows and `.length` / `.reduce` client-side — every list call returns one page (see [pagination.md](pagination.md)), so `result.items.length` after `queryRecordsById({ filter })` returns at most one page's worth, no matter how many rows match. Use `totalCount` for cardinality, `aggregates: [{ function: 'COUNT', field: 'Id' }]` (with `groupBy` for per-bucket counts) for chart data.
8. **File-type fields (`fieldDisplayType === 'File'`) aren't strings.** The record carries only metadata (`{ id, name, size, contentType }`); stringifying gives `"[object Object]"`. To display, call `entities.downloadAttachment(entityId, recordId, fieldName)` → `Blob` → `URL.createObjectURL` for an `
`. **Neither `contentType` nor filename extension is reliable for detecting kind** — DF often returns `application/octet-stream`, and the stored `name` is frequently a bare UUID with no extension. To decide inline render vs download link, either (a) sniff the blob's magic bytes after download (PNG starts `89 50 4E 47`, JPEG `FF D8 FF`, GIF `47 49 46 38`, PDF `25 50 44 46`), or (b) optimistically attempt `
` and swap to a download link in `onError`. Writes go through `uploadAttachment(...)`, not `insertRecordById` / `updateRecordById`.
-9. **`MULTILINE_MAX` fields return a size marker on list/query reads.** `getAllRecords` / `queryRecordsById` return a string starting `HasValue=true Length=N` (live form: `"HasValue=true Length=20000 — call Get Entity Record By Id activity to retrieve content"`), never the content — only `getRecordById` returns the full value (SDK 1.5.2+, v2 read endpoint). Never render or persist the marker as data, and never echo it back through `updateRecordById` / `updateRecordsById` — the server accepts it as a normal value and silently destroys the real content; omit the key instead. The type accepts no filters or `sortOptions` (server 400: *"Field '' is of type MULTILINE_MAX and cannot be used in filters."*). `lengthLimit` is a UTF-16 **byte** budget (max 131072 ≈ 65,536 chars).
+9. **`MULTILINE_MAX` fields return only a preview on list/query reads.** `getAllRecords` / `queryRecordsById` return either the value truncated to 10,000 characters with a `...[Truncated]` suffix or a size marker starting `HasValue=true Length=N` (sometimes with a trailing hint), depending on the tenant; encrypted fields always return `HasValue=true Encrypted=true`. Only `getRecordById` returns the guaranteed full value (SDK 1.5.2+, v2 read endpoint). Never render or persist a preview as data, and never echo it back through `updateRecordById` / `updateRecordsById` — the server accepts it as a normal value and silently destroys the real content; omit the key instead. The type accepts no filters or `sortOptions` (server 400: *"Field '' is of type MULTILINE_MAX and cannot be used in filters."*). `lengthLimit` is a UTF-16 **byte** budget (max 131072 ≈ 65,536 chars).
## Three paths require choice-value translation — don't miss any
diff --git a/skills/uipath-platform/references/data-fabric/data-fabric.md b/skills/uipath-platform/references/data-fabric/data-fabric.md
index 53d6f32a3a..79ff257757 100644
--- a/skills/uipath-platform/references/data-fabric/data-fabric.md
+++ b/skills/uipath-platform/references/data-fabric/data-fabric.md
@@ -111,7 +111,7 @@ Do not change field types, create federated entities, or write federated records
20. **`records import` supports Basic types only.** `CHOICE_SET_*`, `RELATIONSHIP`, `FILE`, `AUTO_NUMBER` columns are ignored on import — optional columns land as `null`; **`isRequired` columns without a `defaultValue` fail the whole row** (`ErrorFileLink` entry per row). Sequence: (1) `entities get` → list unsupported columns; (2) tell the user which columns will be skipped, and which rows will fail because a required unsupported column has no default; (3) offer `records insert --file ` (+ `files upload` for FILE) as the alternative; (4) invoke only after explicit confirmation. See [`bulk-import.md` → Complex Field Types Not Supported](bulk-import.md#complex-field-types-not-supported).
-21. **`MULTILINE_MAX` — marker reads, no filter/sort.** `records list` / `records query` return a size marker (`HasValue=true Length=N`) — full value only via `records get`. Never echo the marker back through `records update` — the server accepts it as a normal value and destroys the real content; omit the key instead. No filter/sort support (400). `lengthLimit` is a UTF-16 byte budget (max 131072 ≈ 65,536 chars). Full contract: [`entity-schema.md` → MULTILINE_MAX](entity-schema.md#multiline_max-fields) + [`records-query.md` → MULTILINE_MAX](records-query.md#multiline_max-fields--marker-vs-full-content).
+21. **`MULTILINE_MAX` — preview reads, no filter/sort.** `records list` / `records query` return a preview, either content truncated to 10,000 characters with a `...[Truncated]` suffix or a size marker (`HasValue=true Length=N`), depending on the tenant; full value only via `records get`. Never echo a preview back through `records update` — the server accepts it as a normal value and destroys the real content; omit the key instead. No filter/sort support (400). `lengthLimit` is a UTF-16 byte budget (max 131072 ≈ 65,536 chars). Full contract: [`entity-schema.md` → MULTILINE_MAX](entity-schema.md#multiline_max-fields) + [`records-query.md` → MULTILINE_MAX](records-query.md#multiline_max-fields--preview-vs-full-content).
---
diff --git a/skills/uipath-platform/references/data-fabric/entity-schema.md b/skills/uipath-platform/references/data-fabric/entity-schema.md
index 9a9bee4f85..266d58f978 100644
--- a/skills/uipath-platform/references/data-fabric/entity-schema.md
+++ b/skills/uipath-platform/references/data-fabric/entity-schema.md
@@ -32,7 +32,7 @@ Pass the exact `EntityFieldDataType` UPPERCASE string — CLI is case-sensitive.
|---|---|---|
| `STRING` | NVARCHAR | Short text (≤4000 chars via `lengthLimit`) |
| `MULTILINE_TEXT` | NVARCHAR(MAX) | Long text (≤10000 chars via `lengthLimit`) |
-| `MULTILINE_MAX` | NVARCHAR(MAX) | Very large text (`lengthLimit` = UTF-16 byte budget, 1–131072; default 128 KB ≈ 65,536 chars max). No filter/sort; list/query reads return a size marker — see [MULTILINE_MAX fields](#multiline_max-fields) |
+| `MULTILINE_MAX` | NVARCHAR(MAX) | Very large text (`lengthLimit` = UTF-16 byte budget, 1–131072; default 128 KB ≈ 65,536 chars max). No filter/sort; list/query reads return a preview, not the guaranteed full value — see [MULTILINE_MAX fields](#multiline_max-fields) |
| `DECIMAL` | DECIMAL | All numbers — `decimalPrecision: 0` for whole; `2` for money |
| `BOOLEAN` | BIT | true/false |
| `DATE` | DATE | Date only |
@@ -80,7 +80,7 @@ If the CLI rejects a `--body` with *"Cannot read properties of undefined (readin
Very large text. Contract differs from `MULTILINE_TEXT`:
1. **Not filterable, not sortable.** Any `queryFilters` or `sortOptions` entry naming a `MULTILINE_MAX` field → 400: *"Field '' is of type MULTILINE_MAX and cannot be used in filters."* / *"Sort field '' is of type MULTILINE_MAX and cannot be used for sorting."* Never offer the field in filter/sort predicates. See [filter contract](filter-platform-contract.md#operator-support-by-field-type).
-2. **List/query reads return a size marker, not content.** `records list` / `records query` return a string starting `HasValue=true Length=N` (live form: `"HasValue=true Length=20000 — call Get Entity Record By Id activity to retrieve content"`); only `records get ` returns the full value. Read + write-back rules in [records-query.md → MULTILINE_MAX fields](records-query.md#multiline_max-fields--marker-vs-full-content).
+2. **List/query reads return a preview, not the guaranteed full value.** Depending on the tenant, `records list` / `records query` return either the value truncated to 10,000 characters with a `...[Truncated]` suffix, or a size marker starting `HasValue=true Length=N` (sometimes with a trailing hint). Encrypted fields always read back `HasValue=true Encrypted=true`. Only `records get ` returns the full value. Read + write-back rules in [records-query.md → MULTILINE_MAX fields](records-query.md#multiline_max-fields--preview-vs-full-content).
3. **On a 400 from `entities create` / `addFields` naming the type**, surface the error verbatim — do NOT retry or silently substitute `MULTILINE_TEXT` (Rule 18).
```bash
diff --git a/skills/uipath-platform/references/data-fabric/records-query.md b/skills/uipath-platform/references/data-fabric/records-query.md
index 979e33a0b6..2cc747e4d3 100644
--- a/skills/uipath-platform/references/data-fabric/records-query.md
+++ b/skills/uipath-platform/references/data-fabric/records-query.md
@@ -16,16 +16,21 @@ Response wrapper: `{ Result, Code: "RecordList" | "RecordQuery", Data: { Items,
- **`Data.NextCursor` is an object `{ "Value": "" }`, not a flat string.** Pass `Data.NextCursor.Value` to `--cursor` on the next call (unwrap one level). Passing the whole `NextCursor` object errors out.
- Use `Data.HasNextPage` to check if more records exist. Stop when it's `false`.
-## MULTILINE_MAX Fields — Marker vs Full Content
+## MULTILINE_MAX Fields — Preview vs Full Content
-`records list` and `records query` do NOT return `MULTILINE_MAX` content. Each such field comes back as a size marker string starting `HasValue=true Length=N` — live form: `"HasValue=true Length=20000 — call Get Entity Record By Id activity to retrieve content"`. Only single-record read returns the full content:
+`records list` and `records query` do NOT reliably return `MULTILINE_MAX` content. Each such field comes back as a **preview**, and which form you get depends on the tenant:
+
+- the value truncated to 10,000 characters with a `...[Truncated]` suffix (a value at or under 10,000 characters can come back whole), or
+- a size marker starting `HasValue=true Length=N`, sometimes with a trailing hint such as `"HasValue=true Length=20000 — call Get Entity Record By Id activity to retrieve content"`.
+
+An encrypted `MULTILINE_MAX` field always reads back as `HasValue=true Encrypted=true` and never returns content. Do not branch on which form you got; treat any of them as a preview. Only the single-record read returns the full value:
```bash
uip df records get --output json
```
-1. **Never treat the marker as the value.** Don't display, compare, or persist `"HasValue=true Length=N"` as field content — fetch via `records get` first.
-2. **Never write the marker back.** A `records update` body built by echoing a record from `list` / `query` overwrites the real content with the literal marker string — verified: the server accepts it as a normal value, `Result: Success`, content silently destroyed. Omit `MULTILINE_MAX` keys from update bodies unless intentionally replacing the content.
+1. **Never treat a preview as the value.** Don't display, compare, or persist what `list` / `query` returned for the field; fetch via `records get` first. A truncated preview is the more dangerous form because it looks like ordinary content.
+2. **Never write a preview back.** A `records update` body built by echoing a record from `list` / `query` overwrites the real content with the preview — verified: the server accepts it as a normal value, `Result: Success`, content silently destroyed. With a truncated preview the stored value keeps its first 10,000 characters and loses the rest, which is far harder to notice than a marker string. Omit `MULTILINE_MAX` keys from update bodies unless intentionally replacing the content.
3. **No filter, no sort.** `queryFilters` / `sortOptions` naming a `MULTILINE_MAX` field → 400: *"Field '' is of type MULTILINE_MAX and cannot be used in filters."* / *"Sort field '' is of type MULTILINE_MAX and cannot be used for sorting."* Surface verbatim (data-fabric.md Rule 18); don't retry with other operators. Full type contract: [entity-schema.md → MULTILINE_MAX fields](entity-schema.md#multiline_max-fields).
## Pagination
diff --git a/tests/tasks/uipath-platform/data-fabric/integration_multiline_max.yaml b/tests/tasks/uipath-platform/data-fabric/integration_multiline_max.yaml
index e7e5a66bd6..20992d4abb 100644
--- a/tests/tasks/uipath-platform/data-fabric/integration_multiline_max.yaml
+++ b/tests/tasks/uipath-platform/data-fabric/integration_multiline_max.yaml
@@ -1,10 +1,10 @@
task_id: skill-datafabric-integration-multiline-max
description: >
Integration: MULTILINE_MAX lifecycle — create an entity with a MULTILINE_MAX
- field, insert ~20k-char content, observe the size marker on records list,
- retrieve full content via records get, and surface the server-side filter
- rejection verbatim without retrying (Rules 18 + 21). Requires the
- MultilineMax feature flag enabled on the test tenant.
+ field, insert ~20k-char content, observe that records list returns only a
+ preview of it, retrieve the full content via records get, and surface the
+ server-side filter rejection verbatim without retrying (Rules 18 + 21).
+ Requires the MultilineMax feature enabled on the test tenant.
tags: [uipath-platform, data-fabric, integration, entities, records, mode:build, lifecycle:setup]
run_limits:
@@ -72,25 +72,34 @@ success_criteria:
pass_threshold: 1.0
- type: llm_judge
- description: "Agent explained the marker-vs-full contract and surfaced the filter rejection without silent workarounds"
+ description: "Agent explained the preview-vs-full contract and surfaced the filter rejection without silent workarounds"
include_agent_output: true
prompt: |
The agent worked against a Data Fabric entity whose Body field is
MULTILINE_MAX. Platform contract: `records list` / `records query`
- return a size marker string starting "HasValue=true Length=N" (with a
- trailing hint about Get Entity Record By Id) for such fields; only
- `records get` returns the full content; server-side filters on the
+ return only a PREVIEW of such a field, never the guaranteed full value.
+ The preview takes one of two forms depending on the tenant, and BOTH are
+ correct platform behaviour:
+ - the content truncated to 10,000 characters with a "...[Truncated]"
+ suffix, or
+ - a size marker string starting "HasValue=true Length=N", sometimes
+ with a trailing hint about Get Entity Record By Id.
+ Only `records get` returns the full content. Server-side filters on the
field are rejected with HTTP 400 ("Field 'Body' is of type
MULTILINE_MAX and cannot be used in filters.").
Read the agent's final response. Score on three points:
- a) The agent showed that `records list` returned a size marker (not the
- content) for Body, and showed the full ~20,000-char content (or a
+ a) The agent showed what `records list` returned for Body and it was a
+ preview in either of the two forms above (i.e. not the full ~20,000
+ characters), and showed the full ~20,000-char content (or a
clearly-labelled excerpt of it) obtained via the single-record read.
- b) The agent explained the difference correctly (list/query return a
- marker; the single-record read returns full content) — not a wrong
- theory like truncation, encoding, or a bug.
+ b) The agent explained the difference correctly: list/query give a
+ bounded preview and the single-record read gives the full content.
+ Describing the preview as truncated content, or as a size marker,
+ is correct as long as it matches what the tenant actually returned.
+ Score this point false only for a wrong theory, such as claiming
+ list returns the complete value, or blaming encoding or a bug.
c) For the "contains lorem" filter request, the agent either surfaced
the server's rejection verbatim (real error text/code) or stated
up-front that MULTILINE_MAX is not filterable citing the platform