You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
core-host: a Project name cut at 120 UTF-16 units stores half an emoji #2638
String.prototype.slice counts UTF-16 units, so the 120 bound at :463 cuts a surrogate pair in half when a Project name ends in an emoji at the bound. createProject stores the half pair; it reaches state.json, the Projects sidebar (core/src/client/settings.js:358 renders project.name) and every panel that reads the record. The client has no maxLength on the Name input (core/src/client/settings.js:414), so a person can type or paste such a name.
Reproduction (run on this machine, the real module)
node repro-store-name.mjs # installs core/src/host/store.js, creates a Project, saves, loads it back
typed : 120 code points / 121 UTF-16 units
file : "PP\\ud83d" (JSON escape written to state.json)
loaded: 120 units; last unit 0xd83d ; isWellFormed = false
utf8 : efbfbd <- tail bytes (efbfbd = U+FFFD)
roundtrip JSON.parse(JSON.stringify): false
Input: 'P'.repeat(119) + '😀' (120 characters, 121 units). The name is accepted, cut at unit 120, and stored with a lone high surrogate 0xd83d. On load it is still not well formed, and encoding it as UTF-8 produces EF BF BD (U+FFFD), so the name shows � where the emoji was.
Expected
A name of at most 120 characters is stored whole (121 units) or, if the unit budget must stay 120, the emoji is dropped whole and the value stays well formed. The same projectText bounds defaultBranch (120), workDir (400) and status (40), so fix the helper once.
with cut from core/src/shared/text-boundary.js (already re-exported by core/src/host/text.js and used for the sibling bounds in #1908/#1912/#1916/#1979/#2005). A test should pin isWellFormed() and the stored length for 'P'.repeat(119) + '😀'.
Reproduced at ff7b384d0c83 by the audit run against the real core/src/host/store.js (isolated home, repo untouched): a 120-code-point Project name ending in an emoji is cut at UTF-16 unit 120, leaves a lone high surrogate in state.json, and encodes to EF BF BD on any UTF-8 write.
Scope for the fix: projectText only (store.js:421), so name/repository/defaultBranch/ownerUserId/workDir/status/digest all go through the one helper. Test: a name whose last code point is an emoji at the limit must round-trip through save()/load() well-formed, and the same input must be unchanged when it fits.
Do not change the limits themselves; the defect is where the cut lands, not how long the field is.
Add changelog.d/2638.fixed.md. No client change needed.
Activity
HugoXK commentedon Nov 7, 2026
Claim
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: fb1ce92c14cd41eba7dec6b5c1205d0f
Branch: dev/2638-core-host-a-project-name-cut-at-120-utf
Base: ff7b384
At: 2026-11-07T20:41:54Z
Birfy commentedon Nov 7, 2026
Written-by: Chief
Triage: agent-ready.
ff7b384d0c83by the audit run against the realcore/src/host/store.js(isolated home, repo untouched): a 120-code-point Project name ending in an emoji is cut at UTF-16 unit 120, leaves a lone high surrogate instate.json, and encodes toEF BF BDon any UTF-8 write.core/src/shared/text-boundary.jscut()(core: cut() stores a lone surrogate the input already carried #1963/Fix the remaining UTF-16-unit string cuts: lone surrogates in stored failure text, task cues, room shares, avatars, role labels and timeline labels #2581) andconstants.jsMAX_ENTRY(core-host: count a Project memory entry in code points, not UTF-16 units #1886) count code points.projectTextis the remaining call site that bypasses it.projectTextonly (store.js:421), so name/repository/defaultBranch/ownerUserId/workDir/status/digest all go through the one helper. Test: a name whose last code point is an emoji at the limit must round-trip throughsave()/load()well-formed, and the same input must be unchanged when it fits.changelog.d/2638.fixed.md. No client change needed.Owner: Birfy
Reviewer: Reviewer
Cut Project text on a code point boundary
Cut Project text fields on a code point boundary (ThinkFlowLab#2640)
Release v0.2.27 (ThinkFlowLab#2701)