davila7/claude-code-templates · error
sessionId and message are required
Error message
sessionId and message are required
What it means
HTTP 400 from the claude-api-proxy POST /api/send-message endpoint when the request body lacks sessionId or message (projectPath is optional). It's a plain required-field validation before the proxy attempts to spawn/talk to Claude.
Source
Thrown at cli-tool/src/claude-api-proxy.js:54
setupRoutes() {
// Get active conversations/sessions
this.app.get('/api/sessions', async (req, res) => {
try {
const sessions = await this.getActiveSessions();
res.json({ sessions });
} catch (error) {
console.error('Error getting sessions:', error);
res.status(500).json({ error: error.message });
}
});
// Send message to Claude (main endpoint)
this.app.post('/api/send-message', async (req, res) => {
try {
const { sessionId, message, projectPath } = req.body;
if (!sessionId || !message) {
return res.status(400).json({ error: 'sessionId and message are required' });
}
const result = await this.sendMessageToClaude(sessionId, message, projectPath);
res.json(result);
} catch (error) {
console.error('Error sending message:', error);
res.status(500).json({ error: error.message });
}
});
// Get conversation history
this.app.get('/api/conversation/:sessionId', async (req, res) => {
try {
const { sessionId } = req.params;
const conversation = await this.getConversationHistory(sessionId);
res.json({ conversation });
} catch (error) {View on GitHub (pinned to a0851ed10c)
Solutions
- Ensure the request has header Content-Type: application/json and a body like {"sessionId":"...","message":"..."}
- Create a session first (or reuse an existing session id) and include it in the payload
- Trim/guard the message field client-side before enabling the send button
- Check for accidental typos in field names (session_id vs sessionId)
Example fix
// before
fetch('/api/send-message', { method: 'POST', body: JSON.stringify({ message }) });
// after
fetch('/api/send-message', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sessionId, message })
}); Defensive patterns
Strategy: validation
Validate before calling
if (!sessionId || !String(message).trim()) throw new Error('missing sessionId or message');
await fetch('/api/send-message', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sessionId, message: message.trim(), projectPath })
}); Type guard
const isSendPayload = (b) => typeof b?.sessionId === 'string' && b.sessionId.length > 0 && typeof b?.message === 'string' && b.message.trim().length > 0;
Try / catch
catch (e) { if (e.status === 400) disableSendUntilFieldsValid(); else throw e; } Prevention
- Always send Content-Type: application/json
- Disable submit until both fields are non-empty
- Use exact field names sessionId/message
When it happens
Trigger: POST /api/send-message with a JSON body missing sessionId, missing message, or with either falsy (empty string / null); also when the body isn't parsed as JSON so both destructure to undefined.
Common situations: Client forgot to create/attach a session id before sending; sending form-encoded or text/plain body to an endpoint that expects req.body JSON (missing content-type: application/json); frontend race where the message input is empty but submit fired.
Related errors
- Please provide a detailed prompt (at least 10 characters)
- Agent name is required
- Invalid cache type. Use "all" or "conversations"
- Invalid agent name
- Invalid workflow hash format. Expected format: #hash
AI-assisted analysis of davila7/claude-code-templates@a0851ed10c (2026-08-28).
Data as JSON: /api/errors/ff1af3aabb2efa41.
Report an issue: GitHub.