Part of an ActiveAgent + actionagent dashboard functional review (multi-agent, adversarially verified). Severity: 🟠 Major.
The Templates feature is broken three ways on the engine: POST /api/templates/:id/use calls create_agent_for(current_user) which crashes on a nil user (the engine's default no-auth mode) and bypasses the owner abstraction; ToolDiscovery crashes on a Hash-shaped agent.mcp_servers — the exact shape the seeded "PlaywrightMCP Demo" template writes — 500-ing /api/tools and /api/mcp_servers for the whole workspace; and AgentTemplate.seed_defaults! exists but nothing ever calls it, so the Template Library is permanently empty despite prominent "Browse Templates" CTAs.
Findings
Engine POST /api/templates/:id/use 500s: create_agent_for(current_user) crashes on nil user and bypasses the owner abstraction
- Where:
actionagent/app/controllers/action_agent/api/templates_controller.rb:37 · severity: major · kind: bug · repo: activeagent
- What breaks: ActionAgent::Api::TemplatesController#use passes current_user into AgentTemplate#create_agent_for, which calls user.agents.build. In a single-user/no-auth install (the engine's default mode; ActionAgent.authentication_method nil, so current_user resolves to nil via ApplicationController#resolve_actor) every 'Use This Template' click raises NoMethodError and returns 500. Even in authenticated hosts it assumes the host's user model has an
agents association pointing at ActionAgent::Agent, bypassing the engine's own ownership abstraction — AgentsController#create correctly uses owner_agents.build (agents_controller.rb:71). The frontend swallows the failure (TemplateLibrary.jsx:51 only handles response.ok), so the button shows 'Creating...' then silently does nothing. No engine test covers templates at all.
- Evidence: Live proof on the dummy (after seeding templates via ActionAgent::AgentTemplate.seed_defaults!): curl -X POST http://localhost:3001/activeagents/api/templates/1/use -d '{"name":"Probe Agent"}' -> HTTP 500, exception page shows "undefined method `agents' for nil" at actionagent/app/models/action_agent/agent_template.rb:29 (user.agents.build). current_user nil path: actionagent/app/controllers/action_agent/application_controller.rb:49-58. Correct pattern in same API: actionagent/app/controllers/action_agent/api/agents_controller.rb:71 (owner_agents.build). Silent frontend: actionagent/frontend/components/dashboard/TemplateLibrary.jsx:51-54.
- Suggested fix: In TemplatesController#use, build through the engine's ownership layer instead of the host user's association: agent = owner_agents.build(name: params[:name].presence || @template.name, description: @template.description, provider: @template.provider, model: @template.model, instructions: @template.instructions, preset_type: @template.preset_type, appearance: @template.appearance, instruction_sets: @template.instruction_sets, tools: @template.tools, mcp_servers: @template.mcp_servers, model_config: @template.model_config, status: :draft); if agent.save then @template.increment!(:usage_count) and render :created else render 422 with agent.errors.full_messages. Cleanest shape: change AgentTemplate#create_agent_for to accept a relation (create_agent_in(relation, name:)) so the model keeps the attribute mapping and the controller passes owner_agents — this works for nil owner because Agent.for_owner(nil)/agents_for(nil) returns the unowned relation in single-user installs. Add an engine integration test hitting POST /api/templates/:id/use with no auth configured (mirror existing engine API test setup). Separately, TemplateLibrary.jsx handleUseTemplate should surface !response.ok (e.g. set an error state) instead of silently resetting isCreating.
ToolDiscovery crashes on Hash-shaped agent.mcp_servers — the exact shape the seeded PlaywrightMCP Demo template writes — 500ing /api/tools and /api/mcp_servers for the whole workspace
- Where:
actionagent/app/services/action_agent/tool_discovery.rb:568 · severity: major · kind: bug · repo: activeagent
- What breaks: ToolDiscovery#merge_configured_tools iterates Array(agent.mcp_servers). The seeded 'PlaywrightMCP Demo' template stores mcp_servers as a top-level Hash ({"playwright" => {command:...}}, agent_template.rb:161-166) and AgentTemplate#create_agent_for copies it verbatim onto the agent (agent_template.rb:39), while agents everywhere else use an Array (engine strong params permit mcp_servers: [], agents_controller.rb:320; dummy/app schema default []). Array(hash) yields [key, value] pair Arrays, and mcp_server_key then does server["key"] on an Array -> TypeError. Once any agent in the workspace has this shape, GET /api/tools AND GET /api/mcp_servers both 500 — the Tools view and MCP Services view are dead until the row is deleted. The existing test only covers an Array-of-hashes entry ('accepts an agent mcp_servers entry given as a hash', tool_discovery_test.rb:348), not the seed's top-level Hash.
- Evidence: Reproduced live on the dummy: created an agent exactly as create_agent_for would (mcp_servers: AgentTemplate.find_by(slug: "playwright-mcp-demo").mcp_servers, stored as Hash {"playwright"=>{"command"=>"npx",...}}); then curl http://localhost:3001/activeagents/api/tools -> HTTP 500 and /api/mcp_servers -> HTTP 500, exception page: TypeError (no implicit conversion of String into Integer) at tool_discovery.rb:568 via tool_discovery.rb:262-263 (merge_configured_tools). Deleting the probe agent restored both endpoints to 200. Crash site: tool_discovery.rb:564-569 (mcp_server_key). Seed shape: actionagent/app/models/action_agent/agent_template.rb:161-166.
- Suggested fix: In actionagent/app/services/action_agent/tool_discovery.rb merge_configured_tools: normalize before iterating — if agent.mcp_servers.is_a?(Hash), treat its keys as server names (agent.mcp_servers.keys), else Array(...). Tighten mcp_server_key to return nil unless server.is_a?(Hash) (or responds to :key?), so stray Arrays/scalars are skipped instead of raising. Normalize the PlaywrightMCP Demo seed to the array shape ([{"name"=>"playwright", "command"=>"npx", "args"=>[...]}]) in BOTH actionagent/app/models/action_agent/agent_template.rb:161-166 and activeagents app/models/agent_template.rb (same lines), since both repos' agents.mcp_servers contract is an array (strong params mcp_servers: []). Add a regression test with an agent whose mcp_servers is a top-level Hash asserting /api/tools and /api/mcp_servers return 200 and the server key appears.
Engine Template Library is permanently empty: AgentTemplate.seed_defaults! exists but nothing ever calls it
- Where:
actionagent/app/models/action_agent/agent_template.rb:52 · severity: minor · kind: missing · repo: activeagent
- What breaks: The engine ships the full seed set (ActionAgent::AgentTemplate.seed_defaults!, agent_template.rb:52-180) and the dashboard advertises the feature prominently — 'Browse Templates' buttons in the agent list and empty state (AgentList.jsx:160, 296) opening the TemplateLibrary modal ('Start with a pre-configured agent template'). But no code path in the repo invokes seed_defaults!: not the install generator (lib/generators/action_agent/install_generator.rb), no rake task, no engine seeds, and docs/framework/dashboard.md never mentions templates. Every fresh engine install therefore shows an empty library ('No templates found in this category') forever, and the use flow is unreachable. The app sibling seeds them from db/seeds.rb:9 — that call site was lost in the extraction.
- Evidence: grep -rn seed_defaults across /home/user/activeagent finds only the definition (no callers); the app calls it at activeagents/db/seeds.rb:9. Live: GET http://localhost:3001/activeagents/api/templates on the untouched dummy DB -> {"templates":[],...} (HTTP 200). UI entry points: actionagent/frontend/components/dashboard/AgentList.jsx:160,296; modal: frontend/pages/Dashboard.jsx:462-466.
- Suggested fix: Add a caller in the engine: either a rake task (e.g. lib/tasks/action_agent.rake defining action_agent:seed_templates that runs ActionAgent::AgentTemplate.seed_defaults!) invoked/printed by the install generator's post-install instructions, or lazy-seed in ActionAgent::Api::TemplatesController#index when AgentTemplate.none? (matches seed_defaults!'s idempotent find_or_create_by! design). Document the step in docs/framework/dashboard.md. Correct the frontend citation lines to AgentList.jsx:166 and :302. (The PlaywrightMCP mcp_servers shape issue is a separate finding; do not bundle it here.)
Verification
Each finding above was produced by a dedicated per-feature review agent, then confirmed by an independent adversarial verifier (all rated high-confidence; zero rejected in this set). File:line citations are against the current main/HEAD of each repo; many were reproduced live against a booted dashboard.
The Templates feature is broken three ways on the engine:
POST /api/templates/:id/usecallscreate_agent_for(current_user)which crashes on a nil user (the engine's default no-auth mode) and bypasses the owner abstraction;ToolDiscoverycrashes on a Hash-shapedagent.mcp_servers— the exact shape the seeded "PlaywrightMCP Demo" template writes — 500-ing/api/toolsand/api/mcp_serversfor the whole workspace; andAgentTemplate.seed_defaults!exists but nothing ever calls it, so the Template Library is permanently empty despite prominent "Browse Templates" CTAs.Findings
Engine POST /api/templates/:id/use 500s: create_agent_for(current_user) crashes on nil user and bypasses the owner abstraction
actionagent/app/controllers/action_agent/api/templates_controller.rb:37· severity: major · kind: bug · repo:activeagentagentsassociation pointing at ActionAgent::Agent, bypassing the engine's own ownership abstraction — AgentsController#create correctly uses owner_agents.build (agents_controller.rb:71). The frontend swallows the failure (TemplateLibrary.jsx:51 only handles response.ok), so the button shows 'Creating...' then silently does nothing. No engine test covers templates at all.ToolDiscovery crashes on Hash-shaped agent.mcp_servers — the exact shape the seeded PlaywrightMCP Demo template writes — 500ing /api/tools and /api/mcp_servers for the whole workspace
actionagent/app/services/action_agent/tool_discovery.rb:568· severity: major · kind: bug · repo:activeagentEngine Template Library is permanently empty: AgentTemplate.seed_defaults! exists but nothing ever calls it
actionagent/app/models/action_agent/agent_template.rb:52· severity: minor · kind: missing · repo:activeagentVerification
Each finding above was produced by a dedicated per-feature review agent, then confirmed by an independent adversarial verifier (all rated high-confidence; zero rejected in this set). File:line citations are against the current
main/HEAD of each repo; many were reproduced live against a booted dashboard.