Background
A production crash on mobile was root-caused to single paste rows larger than 10MB (Android requery CursorWindow limitation; the read side has already been fixed in the mobile repos). The main source of such rows is copying very large text on desktop, which then syncs to mobile.
This adds a write-side defense shared across all three platforms via commonMain: oversized non-file paste content is discarded before it is persisted.
Scope
The limit applies only to non-file carrier types (text / HTML / RTF / URL / color). Files and images store their payload on disk and remain governed by the existing sync file size limit. Naming, config keys, and settings copy all say "non-file" explicitly to avoid implying that all pastes are limited.
- New config:
enabledNonFilePasteSizeLimit (default true) and maxNonFilePasteSize (MB, default 8), following the enabledSyncFileSizeLimit/maxSyncFileSize style.
- New
commonMain process plugin DiscardOversizedNonFilePlugin, registered right after RemoveInvalidPlugin: oversized non-file items are filtered out (silent flavor degradation, log only); when every item is discarded, one notification is shown and the existing empty-list path mark-deletes the paste row.
- Remote receive path (
releaseRemotePasteData) bypasses the plugin pipeline, so it gets a dedicated pre-persist check: any oversized non-file item skips the whole paste (flavor degradation would break hash/content consistency used by same-hash dedup) and notifies with the source device name. The sender keeps the full data, so nothing is lost.
- Desktop settings UI: switch + size counter next to the sync file size limit, with copy that spells out the affected types and the file/image exemption.
- i18n keys added to all 10 languages.
Out of scope
- No sender-side skip and no spilling large text to file storage (possible future work).
- Mobile follow-up (config implementations, DI registration, settings UI) happens in the mobile repos after this lands.
Background
A production crash on mobile was root-caused to single paste rows larger than 10MB (Android
requeryCursorWindow limitation; the read side has already been fixed in the mobile repos). The main source of such rows is copying very large text on desktop, which then syncs to mobile.This adds a write-side defense shared across all three platforms via
commonMain: oversized non-file paste content is discarded before it is persisted.Scope
The limit applies only to non-file carrier types (text / HTML / RTF / URL / color). Files and images store their payload on disk and remain governed by the existing sync file size limit. Naming, config keys, and settings copy all say "non-file" explicitly to avoid implying that all pastes are limited.
enabledNonFilePasteSizeLimit(defaulttrue) andmaxNonFilePasteSize(MB, default8), following theenabledSyncFileSizeLimit/maxSyncFileSizestyle.commonMainprocess pluginDiscardOversizedNonFilePlugin, registered right afterRemoveInvalidPlugin: oversized non-file items are filtered out (silent flavor degradation, log only); when every item is discarded, one notification is shown and the existing empty-list path mark-deletes the paste row.releaseRemotePasteData) bypasses the plugin pipeline, so it gets a dedicated pre-persist check: any oversized non-file item skips the whole paste (flavor degradation would break hash/content consistency used by same-hash dedup) and notifies with the source device name. The sender keeps the full data, so nothing is lost.Out of scope