xai-org/x-algorithm · error · SemanticCheckFailure
function passed to Foldl() returns %s but seed value is a %s
Error message
function passed to Foldl() returns %s but seed value is a %s
What it means
Foldl (left fold) requires the folding function's return type to be compatible with the seed value's type. If the function diverges from the seed type, the accumulator type would change across iterations, which the statically typed DSL forbids.
Source
Thrown at botmaker/src/java/com/twitter/botmaker/compiler/Compiler.java:931
Type fromType = Type.OBJECT;
if (Collection.class.isAssignableFrom(collectionNode.getReturnType().typeBase)) {
fromType = collectionNode.getReturnType().getTypeParams().get(0);
}
Type seedType = seedValueNode.getReturnType();
CompilerScope scope = context.addScope();
long scopeId = context.currentScopeId();
Parameter parameterA = Parameter.scope(
varA, seedType, scopeId, seedValueNode);
scope.defineVariable(parameterA);
Parameter parameterB = Parameter.scope(
varB, fromType, scopeId, collectionNode);
scope.defineVariable(parameterB);
ASTNode funcNode = createASTNodeTree(context, funcTree);
if (Type.isDivergentTo(funcNode.getReturnType(), seedType)) {
throw new SemanticCheckFailure(
String.format(
"function passed to Foldl() returns %s but seed value is a %s",
funcNode.getReturnType(),
seedType));
}
context.removeScope();
ASTNode result = Fold.createFoldl(exprText, varA, varB, funcNode, seedValueNode,
context.currentScopeId(), collectionNode);
return result;
}
private ASTNode toFoldl1(CompilerContext context, String exprText, Tree root)
throws ParseFailure, SemanticCheckFailure {
String varA = getVariableName(root.getChild(1));
String varB = getVariableName(root.getChild(2));
ASTNode collectionNode = createASTNodeTree(context, root.getChild(4));View on GitHub (pinned to 24c60942c5)
Solutions
- Make the seed's type match the function's return type
- Rewrite the folding function so it returns the same type as its seed argument
- If changing types mid-fold is needed, do the conversion in an outer expression instead
Example fix
// before Foldl(nums, 0L, (acc, x) -> ToDouble(acc + x)) // after Foldl(nums, 0L, (acc, x) -> acc + x)
Defensive patterns
Strategy: type-guard
Type guard
// in DSL: ensure fold fn return type == seed type before compiling
if (!fnReturnType.equals(seedType)) throw new IllegalArgumentException("Foldl seed/fn type mismatch"); Try / catch
catch (SemanticCheckFailure e) { if (e.getMessage().contains("Foldl")) surfaceTypeHint(e); else throw e; } Prevention
- Always start Foldl with a seed of the accumulator type you want
- Keep fold lambdas type-stable
When it happens
Trigger: `Foldl(collection, seed, fn)` where fn returns e.g. Double while seed is a Long, or fn returns a struct while the seed is a primitive.
Common situations: Writing a fold that accumulates a different type than it takes (e.g. summing into a string, or building a list from an int seed), or assuming implicit numeric coercion that Botmaker does not perform.
Related errors
- Foldl1 is expected to return %s but passed function returns
- Sort is expected to return %s but passed function returns %s
- Parameter #%d of %s should be %s, received %s instead
- Contains expects input of String, Map, Set or Collection typ
- Copy function only supports Map or StructTuple.
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/b1143b2ccd6d7472.
Report an issue: GitHub.