Common issues, error messages, and solutions for the code_execution tool.
- Configuration Issues
- Syntax Errors
- Runtime Errors
- Timeout Issues
- Tool Call Errors
- Serialization Errors
- Performance Issues
- Debugging Tips
Symptom:
Error: code_execution is disabled in configuration. Set 'enable_code_execution: true' in config file.
Cause: The code_execution feature is disabled by default for security.
Solution:
- Edit your configuration file (
~/.mcpproxy/mcp_config.json) - Add or update:
"enable_code_execution": true - Restart mcpproxy:
pkill mcpproxy && mcpproxy serve
Example Configuration:
{
"enable_code_execution": true,
"code_execution_timeout_ms": 120000,
"code_execution_max_tool_calls": 0,
"code_execution_pool_size": 10,
"mcpServers": [...]
}Symptom: LLM agent lists available tools but code_execution is missing.
Cause: Feature is not enabled or server didn't restart after configuration change.
Solution:
- Verify configuration has
"enable_code_execution": true - Restart mcpproxy server
- Reconnect LLM client
- List tools again
Verification:
# Check if code_execution tool is registered
mcpproxy call tool --tool-name=retrieve_tools --json_args='{"query":"code execution"}'Symptom:
{
"ok": false,
"error": {
"message": "timeout_ms must be between 1 and 600000 milliseconds"
}
}Cause: Invalid timeout_ms value in request options.
Solution: Use a timeout between 1ms and 600000ms (10 minutes):
{
"code": "...",
"options": {
"timeout_ms": 120000 // 2 minutes (valid)
}
}Symptom:
{
"ok": false,
"error": {
"code": "SYNTAX_ERROR",
"message": "SyntaxError: Unexpected token '{'",
"stack": ""
}
}Common Causes:
- Missing closing brackets/braces
- Invalid JavaScript syntax
Solutions:
Problem: Missing brackets
// Bad
const x = { value: 1, missing: 2
// Good
const x = { value: 1, missing: 2 };Problem: Incomplete expressions
// Bad
const msg = `Hello, ${
// Good
const msg = `Hello, ${name}!`;Symptom: Code execution fails with "end of input" error.
Cause: Incomplete JavaScript expression or statement.
Solution: Ensure all blocks are properly closed:
// Bad
var x = function() {
return 42;
// Missing closing brace
// Good
var x = function() {
return 42;
};Symptom:
{
"ok": false,
"error": {
"code": "RUNTIME_ERROR",
"message": "TypeError: Cannot read property 'name' of undefined",
"stack": "..."
}
}Cause: Accessing properties on undefined or null values.
Solution: Always check values before accessing properties:
// Bad
var name = input.user.name; // Crashes if input.user is undefined
// Good
var name = input.user ? input.user.name : 'Unknown';
// Better
var name = 'Unknown';
if (input && input.user && input.user.name) {
name = input.user.name;
}For Tool Calls:
// Bad
var user = call_tool('github', 'get_user', {username: input.username});
var name = user.result.name; // Crashes if user.ok is false
// Good
var user = call_tool('github', 'get_user', {username: input.username});
if (!user.ok) {
return {error: user.error.message};
}
var name = user.result.name;Symptom:
{
"ok": false,
"error": {
"code": "RUNTIME_ERROR",
"message": "ReferenceError: myVariable is not defined",
"stack": "..."
}
}Cause: Using variables or functions that don't exist.
Common Mistakes:
Problem: Undefined variables
// Bad
return result; // 'result' was never declared
// Good
var result = 42;
return result;Problem: Using unavailable functions
// Bad
var data = require('fs').readFileSync('file.txt'); // require() not available
// Bad
setTimeout(function() { doWork(); }, 1000); // setTimeout() not available
// Good
var data = call_tool('filesystem', 'read_file', {path: 'file.txt'});Symptom: Execution fails with stack overflow.
Cause: Infinite recursion or very deep recursion.
Solution: Check for infinite loops or recursive calls:
// Bad
function factorial(n) {
return n * factorial(n - 1); // No base case!
}
// Good
function factorial(n) {
if (n <= 1) return 1; // Base case
return n * factorial(n - 1);
}
// Better (iterative)
function factorial(n) {
var result = 1;
for (var i = 2; i <= n; i++) {
result *= i;
}
return result;
}Symptom:
{
"ok": false,
"error": {
"code": "TIMEOUT",
"message": "JavaScript execution timed out",
"stack": ""
}
}Common Causes:
- Infinite loops
- Too many tool calls
- Slow upstream servers
- Heavy computation
Solutions:
Problem: Infinite loop
// Bad
while (true) {
// This will timeout
}
// Bad
for (var i = 0; i < 1000000000; i++) {
// This takes too long
}
// Good
for (var i = 0; i < input.items.length; i++) {
// Bounded loop
}Problem: Insufficient timeout for workload
// Bad: Default 2-minute timeout for 100 tool calls
{
"code": "for(var i=0;i<100;i++){call_tool(...)}",
"options": {"timeout_ms": 120000} // Might not be enough
}
// Good: Increase timeout for heavy workloads
{
"code": "for(var i=0;i<100;i++){call_tool(...)}",
"options": {"timeout_ms": 300000} // 5 minutes
}Problem: Slow upstream tools
// Solution: Reduce number of calls or increase timeout
{
"code": "...",
"options": {
"timeout_ms": 300000, // Increase timeout
"max_tool_calls": 50 // Limit calls to prevent runaway
}
}Symptom:
{
"ok": false,
"error": {
"code": "MAX_TOOL_CALLS_EXCEEDED",
"message": "Exceeded maximum tool calls limit (10)",
"stack": ""
}
}Cause: Code called call_tool() more times than max_tool_calls allows.
Solution:
Option 1: Increase limit
{
"code": "for(var i=0;i<20;i++){call_tool(...)}",
"options": {"max_tool_calls": 25} // Set higher than needed
}Option 2: Reduce tool calls
// Bad: Call tool for every item
for (var i = 0; i < 1000; i++) {
call_tool('api', 'process', {id: items[i]});
}
// Good: Batch items if tool supports it
var batchSize = 100;
for (var i = 0; i < items.length; i += batchSize) {
var batch = items.slice(i, i + batchSize);
call_tool('api', 'process_batch', {items: batch});
}Symptom:
{
"ok": false,
"error": {
"code": "SERVER_NOT_ALLOWED",
"message": "Server 'gitlab' is not in the allowed servers list",
"stack": ""
}
}Cause: Attempted to call a server not in allowed_servers option.
Solution:
Option 1: Add server to allowed list
{
"code": "call_tool('gitlab', 'get_user', {username: 'test'})",
"options": {
"allowed_servers": ["github", "gitlab"] // Add gitlab
}
}Option 2: Remove restriction (allow all servers)
{
"code": "call_tool('gitlab', 'get_user', {username: 'test'})",
"options": {
"allowed_servers": [] // Empty array = all servers allowed
}
}Symptom: call_tool() returns error saying server doesn't exist.
Cause: Server name is incorrect or server is not configured.
Solution:
- Check server name: Verify spelling and case
// Bad
call_tool('GitHub', 'get_user', {}); // Wrong case
// Good
call_tool('github', 'get_user', {}); // Correct name- List available servers:
mcpproxy call tool --tool-name=upstream_servers --json_args='{"operation":"list"}'- Add server if missing:
mcpproxy call tool --tool-name=upstream_servers \
--json_args='{"operation":"add","name":"github","url":"https://api.github.com/mcp","protocol":"http","enabled":true}'Symptom:
{
"ok": false,
"error": {
"code": "SERIALIZATION_ERROR",
"message": "Result contains non-JSON-serializable values (functions, circular references, etc.)",
"stack": ""
}
}Cause: JavaScript return value contains functions, circular references, or other non-JSON types.
Solutions:
Problem: Returning functions
// Bad
return {
calculate: function() { return 42; }
};
// Good
return {
result: 42
};Problem: Returning undefined
// Bad
return undefined; // Not JSON-serializable
// Good
return null; // JSON-serializableProblem: Circular references
// Bad
var obj = {value: 42};
obj.self = obj; // Circular reference
return obj;
// Good
return {value: 42};Problem: Special objects (Date, RegExp)
// Bad
return {
created: new Date() // Date object not JSON-serializable
};
// Good
return {
created: new Date().toISOString() // String is JSON-serializable
};Symptom: Code takes longer than expected to execute.
Diagnosis:
- Check number of tool calls
- Measure upstream tool latency
- Look for inefficient loops
- Check for excessive data processing
Solutions:
Reduce tool calls:
// Bad: N tool calls
for (var i = 0; i < items.length; i++) {
call_tool('api', 'get', {id: items[i]});
}
// Good: 1 batch tool call
call_tool('api', 'get_batch', {ids: items});Cache repeated calls:
// Bad: Call same tool multiple times
for (var i = 0; i < items.length; i++) {
var config = call_tool('api', 'get_config', {}); // Repeated call
process(items[i], config);
}
// Good: Call once, reuse result
var config = call_tool('api', 'get_config', {});
if (!config.ok) return config;
for (var i = 0; i < items.length; i++) {
process(items[i], config.result);
}Optimize loops:
// Bad: Inefficient nested loops
for (var i = 0; i < arr1.length; i++) {
for (var j = 0; j < arr2.length; j++) {
if (arr1[i] === arr2[j]) {
results.push(arr1[i]);
}
}
}
// Good: Use object for O(1) lookup
var set = {};
for (var i = 0; i < arr2.length; i++) {
set[arr2[i]] = true;
}
for (var i = 0; i < arr1.length; i++) {
if (set[arr1[i]]) {
results.push(arr1[i]);
}
}Symptom: Requests take longer to start, or you see "waiting for VM" logs.
Cause: More concurrent executions than pool size allows.
Solution: Increase pool size in configuration:
{
"code_execution_pool_size": 20 // Increase from default 10
}Trade-offs:
- Larger pool = more concurrency, more memory usage
- Smaller pool = less concurrency, less memory usage
Recommendation: Monitor pool usage and adjust based on load.
CLI:
mcpproxy code exec --code="..." --log-level=debugServer: Edit config to set log level:
{
"log_level": "debug"
}What you'll see:
- Tool call details (server, tool name, arguments)
- Execution timing
- Pool acquisition/release
- Detailed error messages
var user = call_tool('github', 'get_user', {username: input.username});
console.log('User response:', JSON.stringify(user)); // Logs to server logs
if (!user.ok) {
console.log('Error occurred:', user.error);
return {error: user.error.message};
}
console.log('User name:', user.result.name);
return {name: user.result.name};Where to find logs: ~/.mcpproxy/logs/main.log (or platform-specific log directory)
Start simple and build up:
// Step 1: Verify input access
return input;
// Step 2: Test tool call
var res = call_tool('github', 'get_user', {username: 'octocat'});
return res;
// Step 3: Add error handling
var res = call_tool('github', 'get_user', {username: 'octocat'});
if (!res.ok) return {error: res.error.message};
return res.result;
// Step 4: Add data transformation
var res = call_tool('github', 'get_user', {username: 'octocat'});
if (!res.ok) return {error: res.error.message};
return {
name: res.result.name,
repos: res.result.public_repos
};Test that your return value is JSON-serializable:
var result = {/* your data */};
// This will throw if result is not serializable
var json = JSON.stringify(result);
// If it succeeds, return it
return result;Wrap risky operations in try-catch or use checks:
// Check before accessing
if (res && res.ok && res.result && res.result.name) {
return {name: res.result.name};
} else {
return {error: 'Invalid response structure'};
}
// For loops, check each iteration
for (var i = 0; i < items.length; i++) {
if (!items[i]) {
console.log('Skipping null item at index', i);
continue;
}
// Process items[i]
}Use the CLI to reproduce issues quickly:
# Save problematic code to file
cat > /tmp/debug.js << 'EOF'
var user = call_tool('github', 'get_user', {username: input.username});
console.log('Response:', JSON.stringify(user));
return user;
EOF
# Run with debug logging
mcpproxy code exec \
--file=/tmp/debug.js \
--input='{"username":"octocat"}' \
--log-level=debugIf you're still stuck after trying these solutions:
- Check the examples: examples.md has 10+ working patterns
- Review API reference: api-reference.md has complete schema
- Read the overview: overview.md explains architecture
- Check server logs:
~/.mcpproxy/logs/main.logfor detailed error messages - File an issue: GitHub Issues
**Environment**:
- MCPProxy version: (run `mcpproxy --version`)
- OS: (macOS/Linux/Windows)
- Configuration: (relevant config fields)
**Code**:
```javascript
// Your JavaScript code hereInput:
{
"input": {...}
}Expected: What you expected to happen
Actual: What actually happened (include full error message)
Logs: Relevant lines from ~/.mcpproxy/logs/main.log
---
## Next Steps
- **Examples**: See [examples.md](examples.md) for working code samples
- **API Reference**: See [api-reference.md](api-reference.md) for complete schema
- **Overview**: See [overview.md](overview.md) for architecture and best practices