{"record":{"id":"5057d4836c502efe","repo":"xai-org/x-algorithm","slug":"type-checking-expression-s-failed-expects-d-arg","errorCode":null,"errorMessage":"type checking expression %s failed: expects %d arguments, %d passed","messagePattern":"type checking expression (.+?) failed: expects (.+?) arguments, (.+?) passed","errorType":"validation","errorClass":"SemanticCheckFailure","httpStatus":null,"severity":"error","filePath":"botmaker/src/java/com/twitter/botmaker/ASTNode.java","lineNumber":264,"sourceCode":"          buildGenericTypeIdToTypeMapping(\n              genericTypeParams.get(i),\n              concreteTypeParams.get(i),\n              recordMap\n          );\n        }\n      }\n    }\n  }\n\n  private void validateSignature() throws SemanticCheckFailure {\n    int minArgs = signature.paramTypes.size();\n    int maxArgs = signature.paramTypes.size() + signature.optParamTypes.size();\n\n    if (signature.varargsType == null) {\n      if (astNodeChildren.size() < minArgs\n          || astNodeChildren.size() > maxArgs) {\n        if (minArgs == maxArgs) {\n          throw new SemanticCheckFailure(String.format(\n              \"type checking expression %s failed: expects %d arguments, %d passed\",\n              exprText,\n              minArgs,\n              astNodeChildren.size()\n          ));\n        } else {\n          throw new SemanticCheckFailure(String.format(\n              \"type checking expression %s failed: expects %d arguments to %d arguments, %d passed\",\n              exprText,\n              minArgs,\n              maxArgs,\n              astNodeChildren.size()\n          ));\n        }\n      }\n    } else {\n      if (astNodeChildren.size() < minArgs) {\n        throw new SemanticCheckFailure(String.format(","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/botmaker/src/java/com/twitter/botmaker/ASTNode.java#L246-L282","documentation":"ThrustAllocator adapts a scratch allocator for Thrust/CUB algorithms used inside XLA GPU utilities: Thrust calls allocate(n) for temporary storage, and the adapter forwards the request to scratch_allocator_->Allocate(n). If the underlying scratch allocator returns an empty optional (cannot satisfy the request), the adapter throws std::runtime_error('Failed to allocate memory'), which propagates out of the Thrust algorithm.","triggerScenarios":"Running any Thrust/CUB-based operation (sort, scan, reduce, unique) in phoenix/xrex/cuda/xla_utils where the temporary storage request exceeds the scratch allocator's remaining capacity or per-allocation limit; scratch arena exhausted by prior ops in the same stream/compilation; or GPU-wide memory pressure making the underlying allocation fail.","commonSituations":"Large sorts or scans requesting big temporaries, shared scratch buffers sized conservatively for typical workloads, memory fragmentation in long-lived processes, concurrent CUDA streams each holding scratch, or running near the GPU memory limit with a large model resident.","solutions":["Free unused GPU tensors/caches before invoking the operation to give the scratch allocator room","Increase the scratch allocator's pool size / growth policy if configurable via handle or environment settings","Process data in smaller chunks so Thrust temporaries fit within the scratch budget","Set a device memory limit or reserve headroom so scratch allocations can succeed; consider cudaMallocAsync-backed allocators if available","If it happens intermittently under concurrency, serialize scratch-heavy ops or give each stream its own allocator"],"exampleFix":"// before\nchar* allocate(std::ptrdiff_t n) {\n  auto result = scratch_allocator_->Allocate(n);\n  if (!result.has_value()) {\n    throw std::runtime_error(\"Failed to allocate memory\");\n  }\n  return static_cast<char*>(result.value());\n}\n\n// after\nchar* allocate(std::ptrdiff_t n) {\n  auto result = scratch_allocator_->Allocate(n);\n  if (!result.has_value()) {\n    // fall back to the CUDA allocator for oversized temporaries\n    void* p = nullptr;\n    XAI_CUDA_CHECK(cudaMalloc(&p, n));\n    return static_cast<char*>(p);\n  }\n  return static_cast<char*>(result.value());\n}","handlingStrategy":"fallback","validationCode":"// Before Thrust-heavy ops:\nsize_t free = 0, total = 0;\ncudaMemGetInfo(&free, &total);\nsize_t thrust_temp_upper = 2 * n * sizeof(KeyT);  // conservative sort estimate\nif (thrust_temp_upper > free) { /* free memory or chunk input */ }","typeGuard":"template <typename Alloc>\nbool allocator_can_satisfy(Alloc& a, std::ptrdiff_t n) {\n  auto probe = a.Allocate(n);\n  return probe.has_value();\n}","tryCatchPattern":"try {\n  thrust::sort(thrust::cuda::par(ThrustAllocator(pool)), begin, end);\n} catch (const std::runtime_error& e) {\n  if (std::string(e.what()) == \"Failed to allocate memory\") {\n    // fallback: smaller chunks, sync+free caches, or cudaMalloc-backed allocator\n    sort_in_chunks(begin, end, chunk);\n  } else {\n    throw;\n  }\n}","preventionTips":["Reserve GPU headroom (e.g. 10-20%) for Thrust temporaries when sizing batches","Pre-grow scratch pools to cover worst-case sort/scan sizes at startup","Use stream-ordered cudaMallocAsync allocators so temporary memory recycles promptly","Free intermediate tensors promptly and avoid holding results while launching new Thrust ops"],"tags":["cuda","thrust","allocator","out-of-memory","scratch-memory","cub"],"backgroundTag":"cuda-out-of-memory","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}