{"record":{"id":"8164ebb9c0923f73","repo":"davila7/claude-code-templates","slug":"agent-name-is-required","errorCode":null,"errorMessage":"Agent name is required","messagePattern":"Agent name is required","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"cli-tool/src/sandbox-server.js","lineNumber":225,"sourceCode":"        progress: task.progress,\n        startTime: task.startTime,\n        endTime: task.endTime,\n        sandboxId: task.sandboxId,\n        output: task.output.slice(-3).join('\\\\n') // Last 3 lines for preview\n    }));\n    \n    res.json({\n        success: true,\n        tasks: tasks.sort((a, b) => new Date(b.startTime) - new Date(a.startTime))\n    });\n});\n\n// API endpoint to install agent\napp.post('/api/install-agent', async (req, res) => {\n    const { agentName } = req.body;\n\n    if (!agentName) {\n        return res.status(400).json({\n            success: false,\n            error: 'Agent name is required'\n        });\n    }\n\n    // SECURITY: agent names are `category/name` slugs. Reject anything else so a\n    // value like \"x; rm -rf ~\" can never reach the child process.\n    if (!/^[A-Za-z0-9._/-]+$/.test(agentName)) {\n        return res.status(400).json({\n            success: false,\n            error: 'Invalid agent name'\n        });\n    }\n\n    try {\n        console.log(chalk.blue('🔧 Installing agent:'), chalk.cyan(agentName));\n\n        // SECURITY: shell:false (default) keeps agentName as a single argv entry —","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/davila7/claude-code-templates/blob/a0851ed10c7c60463dac8cfaaca124cf32d5804d/cli-tool/src/sandbox-server.js#L207-L243","documentation":"POST /api/install-agent requires an agentName field in the JSON body. The endpoint returns 400 immediately when agentName is falsy (missing, empty, null, undefined).","triggerScenarios":"POST /api/install-agent with body {}, {\"agentName\":\"\"}, or {\"agentName\":null}; or a non-JSON request so req.body.agentName is undefined.","commonSituations":"Client UI submits before the agent selector is populated; forgetting Content-Type: application/json; sending a differently named field like name or agent instead of agentName.","solutions":["Send {\"agentName\":\"development-team/frontend-developer\"} in the JSON body with Content-Type: application/json","Check the field name is exactly agentName, matching the component slug format category/name","Guard client-side that a non-empty agent was selected before submitting"],"exampleFix":"// before\n{ \"name\": \"frontend-developer\" }\n// after\n{ \"agentName\": \"development-team/frontend-developer\" }","handlingStrategy":"validation","validationCode":"if (!body?.agentName || typeof body.agentName !== 'string') {\n  throw new Error('agentName is required');\n}","typeGuard":"const hasAgentName = (b) => b != null && typeof b.agentName === 'string' && b.agentName.length > 0;","tryCatchPattern":null,"preventionTips":["Disable the install button until an agent is selected","Send Content-Type: application/json","Use the exact field name agentName with a category/name slug"],"tags":["http-400","validation","missing-field","express"],"backgroundTag":"request-validation-failed","analyzedSha":"a0851ed10c7c60463dac8cfaaca124cf32d5804d","analyzedAt":"2026-08-28T14:11:56.058Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}