Repository navigation
Description
Before submitting
- I searched open and closed issues and did not find a report of this problem.
- I reviewed this report and removed credentials, tokens, private paths, hostnames, and other sensitive data.
Problem
Defining an agent whose name matches an Object.prototype member (for example constructor) breaks the whole subagent runtime. Every subagent_run and even subagent_list_agents fails with overlay.add is not iterable, for every agent, not only the offending one.
Root cause: discoverAgents in lib/agents-config.ts looks up the tool overlay with overlays.entries[parsed.name]. entries is a plain object built in loadToolOverlays (lib/agent-tool-overlay.ts), so for parsed.name === "constructor" the lookup returns the inherited Object.prototype.constructor function instead of undefined. applyToolOverlay only guards overlay === undefined, then spreads overlay.add, which is undefined on that function, and throws. Because the throw happens while discovering all agents, no agent can be listed or launched.
Steps to reproduce
- Create an agent file
agents/constructor.mdin the agent home with frontmattername: constructorand any validtoolslist. Notools.jsonoverlay is needed. - Start a session and call
subagent_list_agents, orsubagent_runwith any other agent (for examplegentle-ai-workerorgentle-ai-explore). - The call fails with
overlay.add is not iterable.
Minimal equivalent in code:
const entries: Record<string, { add: string[]; remove: string[] }> = {};
const overlay = entries["constructor"]; // Object.prototype.constructor, not undefined
[...overlay.add]; // TypeError: overlay.add is not iterableOther names that hit the same path: toString, valueOf, hasOwnProperty, __proto__.
Expected and actual behavior
Expected: an agent with no overlay entry gets its declared tools unchanged, whatever its name; at worst a single invalid agent is reported in errors without affecting the others.
Actual: discovery throws, so every subagent tool call in the session fails with overlay.add is not iterable and no task is created.
Suggested fix: use an own-property lookup, for example Object.hasOwn(overlays.entries, parsed.name) ? overlays.entries[parsed.name] : undefined in discoverAgents, and/or build the overlay maps with Object.create(null) (this also protects the entries[name] = ... writes against a __proto__ key coming from a tools.json file). A regression test in tests/agent-tool-overlay.test.ts that discovers an agent named constructor without an overlay would pin it.
gentle-pi version
4.8.0
Pi version
1.5.2
Operating system
Windows 11 Pro (10.0.26200)
Relevant logs or error output (optional)
overlay.add is not iterable
Returned by subagent_run (agents gentle-ai-worker, gentle-ai-explore) and by subagent_list_agents; subagent_list_tasks reports "No subagent tasks in this session", confirming the failure happens before any task is created.
Activity
kitomc commentedon Nov 14, 2026
Confirming the root cause with a real run, plus a workaround.
I ran gentle-pi 4.8.0's own
discoverAgents(I copiedlib/to a temp directory, because Node refuses type stripping undernode_modules) against a real agent home with 23 agents, one of them namedconstructor. It throwsoverlay.add is not iterable.After renaming that one agent to
revision-max-constructor(thename:field of its file plus its keys insubagents.json,models.jsonandprofiles.json), the same call loads all 23 agents with no errors or notices.subagent_list_agentsandsubagent_runwork again in the running session, without a restart.So the defect is confirmed.
lib/agents-config.ts:242doesoverlays.entries[parsed.name]on a plain object, andapplyToolOverlayinlib/agent-tool-overlay.tsonly guardsoverlay === undefined. An agent named after anObject.prototypemember (constructor,toString,valueOf,hasOwnProperty) gets the inherited function instead ofundefined, and the spread ofoverlay.addthrows.Workaround: do not name an agent
constructor.The suggested fix is unchanged: use
Object.hasOwn(overlays.entries, parsed.name) ? overlays.entries[parsed.name] : undefined, and/or build the overlay maps withObject.create(null), plus a regression test that discovers an agent namedconstructorwithout an overlay.Environment: gentle-pi 4.8.0, Pi 1.5.2, Windows 11.