alibaba/arthas · error · McpError

-32603

-32603

Error message

Maximum task limit reached ({})

What it means

Thrown by InMemoryTaskStore.createTask() when the number of stored tasks has reached maxTasks (default from the Builder). Creation is guarded by a synchronized createTaskLock and checks tasks.size() >= maxTasks; on overflow it throws a CompletionException wrapping a McpError with ErrorCodes.INTERNAL_ERROR (-32603). The limit caps memory use of the in-memory store.

Source

Thrown at arthas-mcp-server/src/main/java/com/taobao/arthas/mcp/server/task/InMemoryTaskStore.java:171

            return new InMemoryTaskStore<>(defaultTtl, defaultPollInterval, messageQueue, maxTasks);
        }
    }

    private final Object createTaskLock = new Object();

    private boolean isSessionValid(TaskEntry entry, String requestSessionId) {
        if (requestSessionId == null) return true;
        String taskSessionId = entry.sessionId();
        if (taskSessionId == null || taskSessionId.isEmpty()) return true;
        return requestSessionId.equals(taskSessionId);
    }

    @Override
    public CompletableFuture<McpSchema.Task> createTask(CreateTaskOptions options) {
        return CompletableFuture.supplyAsync(() -> {
            synchronized (createTaskLock) {
                if (tasks.size() >= maxTasks) {
                    throw new CompletionException(
                        McpError.builder(McpSchema.ErrorCodes.INTERNAL_ERROR)
                            .message("Maximum task limit reached (" + maxTasks + ")")
                            .build()
                    );
                }

                String taskId = options.taskId() != null ? options.taskId() : UUID.randomUUID().toString();
                String now = Instant.now().toString();
                Long ttl = options.requestedTtl() != null ? options.requestedTtl() : defaultTtl;
                Long pollInterval = options.pollInterval() != null ? options.pollInterval() : defaultPollInterval;
                String sessionId = options.sessionId();

                McpSchema.Task task = McpSchema.Task.builder()
                    .taskId(taskId)
                    .status(McpSchema.TaskStatus.WORKING)
                    .createdAt(now)
                    .lastUpdatedAt(now)
                    .ttl(ttl)

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Raise maxTasks via InMemoryTaskStore.Builder().maxTasks(N) to match expected concurrency.
  2. Lower the task TTL so completed/expired tasks free slots sooner.
  3. Back-pressure the client: only create new tasks after prior ones finish or expire.
  4. Ensure tasks actually reach terminal state so they can be evicted; switch to a persistent TaskStore for large scale.

Example fix

// before
InMemoryTaskStore.Builder<McpSchema.ServerTaskPayloadResult> b =
    new InMemoryTaskStore.Builder<>();
store = b.build(); // default maxTasks too low

// after
store = new InMemoryTaskStore.Builder<McpSchema.ServerTaskPayloadResult>()
    .maxTasks(10_000)
    .defaultTtl(Duration.ofMinutes(5).toMillis())
    .build();
Defensive patterns

Strategy: retry

Validate before calling

// Check remaining capacity before creating
int remaining = maxTasks - store.size(); // if a size accessor exists
if (remaining <= 0) {
    // back-pressure: wait for tasks to expire or finish
}

Try / catch

// Retry creation after a short backoff once expired tasks free slots
try {
    return store.createTask(options).join();
} catch (CompletionException e) {
    Throwable c = e.getCause();
    if (c instanceof McpError me && me.getMessage().contains("Maximum task limit")) {
        Thread.sleep(pollInterval);
        return store.createTask(options).join(); // retry once
    }
    throw e;
}

Prevention

When it happens

Trigger: Creating tasks faster than they expire (TTL eviction) or reach terminal state; long TTLs accumulating many tasks; a client loop spawning tasks without waiting for completion; maxTasks configured too low for the workload.

Common situations: Load test or buggy client flooding task creation; low maxTasks default in a multi-tenant server; TTL set so high that evictions never free slots; tasks stuck in WORKING forever consuming slots.

Related errors


AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14). Data as JSON: /api/errors/2bfaae0dd52558fd. Report an issue: GitHub.