Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion server/claude-sdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ function mapCliOptionsToSDK(options = {}) {
// Handle tool permissions
if (settings.skipPermissions && permissionMode !== 'plan') {
// When skipping permissions, use bypassPermissions mode
// Note: This will fail if running as root due to Claude Code security restrictions
sdkOptions.permissionMode = 'bypassPermissions';
} else {
// Map allowed tools
Expand Down Expand Up @@ -353,9 +354,23 @@ async function queryClaudeSDK(command, options = {}, ws) {
let tempDir = null;

try {
// Debug: Log incoming options
console.log('馃攳 [SDK Debug] Incoming options:', JSON.stringify({
sessionId: options.sessionId,
cwd: options.cwd,
projectPath: options.projectPath,
permissionMode: options.permissionMode,
model: options.model,
hasImages: !!(options.images && options.images.length),
toolsSettings: options.toolsSettings
}, null, 2));

// Map CLI options to SDK format
const sdkOptions = mapCliOptionsToSDK(options);

// Debug: Log mapped SDK options
console.log('馃攳 [SDK Debug] Mapped sdkOptions:', JSON.stringify(sdkOptions, null, 2));

// Load MCP configuration
const mcpServers = await loadMcpConfig(options.cwd);
if (mcpServers) {
Expand All @@ -368,6 +383,11 @@ async function queryClaudeSDK(command, options = {}, ws) {
tempImagePaths = imageResult.tempImagePaths;
tempDir = imageResult.tempDir;

// Enable stderr capture for better error messages
sdkOptions.stderr = (message) => {
console.error('[Claude CLI stderr]:', message);
};

// Create SDK query instance
const queryInstance = query({
prompt: finalCommand,
Expand Down Expand Up @@ -456,10 +476,25 @@ async function queryClaudeSDK(command, options = {}, ws) {
// Clean up temporary image files on error
await cleanupTempFiles(tempImagePaths, tempDir);

// Provide more detailed error messages
let errorMessage = error.message;
let errorHint = '';

// Check for specific error patterns
if (error.message && error.message.includes('status code 400')) {
errorMessage = 'API request failed: Invalid request parameters';
errorHint = 'The session may be corrupted. Try starting a new session instead of resuming this one.';
} else if (error.message && error.message.includes('process exited')) {
errorMessage = 'Claude Code process terminated unexpectedly';
errorHint = 'This may be caused by corrupted session data or invalid API request. Consider starting a fresh session.';
}

// Send error to WebSocket
ws.send(JSON.stringify({
type: 'claude-error',
error: error.message
error: errorMessage,
hint: errorHint,
sessionId: capturedSessionId
}));

throw error;
Expand Down
1 change: 1 addition & 0 deletions vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default defineConfig(({ command, mode }) => {
plugins: [react()],
server: {
port: parseInt(env.VITE_PORT) || 5173,
allowedHosts: ['claudeui.a2d2.dev'],
proxy: {
'/api': `http://localhost:${env.PORT || 3001}`,
'/ws': {
Expand Down