plandex-ai/plandex · error

Batch contains too many files: %d (max %d)

Error message

Batch contains too many files: %d (max %d)

What it means

Beyond global limits, GetFileMapHandler enforces a per-batch file count: shared.ContextMapMaxBatchSize (500). If req.MapInputs has more than 500 entries, the handler returns HTTP 400 with 'Batch contains too many files: %d (max %d)'.

Source

Thrown at app/server/handlers/file_maps.go:58

	totalSize := 0
	for path, input := range req.MapInputs {
		// the client should be truncating inputs to the max size, but we'll check here too
		if len(input) > shared.MaxContextMapSingleInputSize {
			http.Error(w, fmt.Sprintf("File %s is too large: %d (max %d)", path, len(input), shared.MaxContextMapSingleInputSize), http.StatusBadRequest)
			return
		}
		totalSize += len(input)
	}

	// On the client, once the total size limit is exceeded, we send empty file maps for remaining files
	if totalSize > shared.MaxContextMapTotalInputSize+10000 {
		http.Error(w, fmt.Sprintf("Max map size exceeded: %d (max %d)", totalSize, shared.MaxContextMapTotalInputSize), http.StatusBadRequest)
		return
	}

	// Check batch size limits
	if len(req.MapInputs) > shared.ContextMapMaxBatchSize {
		http.Error(w, fmt.Sprintf("Batch contains too many files: %d (max %d)", len(req.MapInputs), shared.ContextMapMaxBatchSize), http.StatusBadRequest)
		return
	}

	if int64(totalSize) > shared.ContextMapMaxBatchBytes {
		http.Error(w, fmt.Sprintf("Batch size too large: %d bytes (max %d bytes)", totalSize, shared.ContextMapMaxBatchBytes), http.StatusBadRequest)
		return
	}

	results := make(chan shared.FileMapBodies, 1)

	err := queueProjectMapJob(projectMapJob{
		inputs:  req.MapInputs,
		ctx:     r.Context(),
		results: results,
	})
	if err != nil {
		log.Println("GetFileMapHandler: map queue is full")
		http.Error(w, "Too many project map jobs, please try again later", http.StatusTooManyRequests)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Split MapInputs into batches of at most 500 files
  2. Reuse the CLI batching logic in app/cli/lib/context_shared.go / context_load.go that already chunks on ContextMapMaxBatchSize and ContextMapMaxBatchBytes
  3. Issue sequential batch requests instead of one large request
  4. Verify against the error's reported count that no path duplication is inflating the batch

Example fix

// before
sendMapRequest(inputs) // 800 files
// after
for i := 0; i < len(inputs); i += shared.ContextMapMaxBatchSize {
    end := min(i+shared.ContextMapMaxBatchSize, len(inputs))
    sendMapRequest(inputs[i:end])
}
Defensive patterns

Strategy: validation

Validate before calling

// Client-side batch-count check before sending
if len(inputs) > shared.ContextMapMaxBatchSize { // 500
    return fmt.Errorf("batch has %d files, max %d", len(inputs), shared.ContextMapMaxBatchSize)
}

Prevention

When it happens

Trigger: A request whose MapInputs contains 501–3000 entries — under the 3000 MaxContextMapPaths cap but over the 500-per-batch limit.

Common situations: Clients that batch by the 3000 path limit instead of the 500 batch limit; batcher logic (like MustLoadContext's ContextMapMaxBatchSize check) skipped; hand-written scripts posting all paths at once.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/10dfc9d4755392a7. Report an issue: GitHub.