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
A kiro chat start reads the workspace cli.json in full on the event loop, at any size #23396
On the kiro backend, AcpProvider.__init__ reads the work directory's .kiro/settings/cli.json in full and parses it (_read_cli_overlay, providers/acp.py:294). When a level resolves for the session's model, _apply_effort_overlay then reads, parses and rewrites the whole file again (providers/acp.py:301), and so does the Tool Search write when one is set (providers/acp.py:302). Nothing bounds the file's size.
The constructor runs on the gateway's event loop: session_allocation_parts/get_or_create.py:881 calls the provider factory directly inside async def _get_or_create_impl. While it runs, nothing else on that loop runs. start() then runs the effort write again, and the Tool Search write when one is set, both off the loop (providers/acp_lifecycle.py:69-70). Each of them reads the whole file.
A repository can track .kiro/settings/cli.json, so its size is not under Kiro Crew's or the user's control. workspace_cli_settings.py already refuses to read a git file past _READ_LIMIT (1 << 20 characters).
Reproduction
On main 5cc82ba, with HOME pointed at a scratch folder: work/.kiro/settings/cli.json holds one effort entry for claude-opus-4.7 and a padding array of 100-character strings. AcpProvider(acp_backend=ACP_BACKEND_KIRO, work_dir=work, model="claude-opus-4.7") is timed on the calling thread, each size in a fresh process.
File
Constructor
Peak memory growth
1 KiB
0.001 s
0 MiB
16 MiB
0.23 s
89 MiB
64 MiB
1.04 s
280 MiB
256 MiB
4.31 s
997 MiB
Memory growth is the process's peak RSS after the constructor minus before it. The probe reads the file once for a checksum before the constructor runs, so these are lower bounds. In every run the constructor also rewrote the whole file, because it read the file's own level back and wrote it again.
Fix
#14528 takes these reads out of the constructor and runs the effort and Tool Search writes in start(), off the event loop. Those writes, and a clear, read at most 1 MiB of cli.json (_CLI_JSON_MAX_BYTES, a bounded read) and leave a larger file unread and unchanged. Native skill projection keeps main's own read of the same file, which safe_read_file_bytes caps at 50 MB.
On its head f79b5f9, the constructor takes 0.000 s at 256 MiB, and the pick's writer _write_cli_overlay refuses the 256 MiB file in 0.016 s with no memory growth. With the ceiling raised past the file's size, the same call takes 1.98 s and adds 641 MiB. It holds the cross-process settings lock while it reads, and each other chat starting in that work directory waits on that lock for up to 2 s.
Activity
KiroCrewCaptain commentedon Oct 23, 2026
Thanks for the report. This issue has been triaged by Crew Captain and will be assigned to a maintainer, who will follow up here.
fix(acp): bound the workspace cli.json read and keep it off the event…
fix(acp): bound the workspace cli.json read and keep it off the event…
fix(acp): bound the workspace cli.json read and keep it off the event…
fix(acp): bound the workspace cli.json read and keep it off the event…