{"record":{"id":"358f0caee4b766e7","repo":"xai-org/x-algorithm","slug":"sort-is-expected-to-return-s-but-passed-function","errorCode":null,"errorMessage":"Sort is expected to return %s but passed function returns %s","messagePattern":"Sort is expected to return (.+?) but passed function returns (.+?)","errorType":"validation","errorClass":"SemanticCheckFailure","httpStatus":null,"severity":"error","filePath":"botmaker/src/java/com/twitter/botmaker/compiler/Compiler.java","lineNumber":1017,"sourceCode":"      Type variableType = Type.OBJECT;\n      if (Collection.class.isAssignableFrom(collectionNode.getReturnType().typeBase)) {\n        variableType = collectionNode.getReturnType().getTypeParams().get(0);\n      }\n\n      CompilerScope scope = context.addScope();\n      long scopeId = context.currentScopeId();\n\n      Parameter parameterA = Parameter.scope(\n          varA, variableType, scopeId, collectionNode);\n      scope.defineVariable(parameterA);\n\n      Parameter parameterB = Parameter.scope(\n          varB, variableType, scopeId, collectionNode);\n      scope.defineVariable(parameterB);\n\n      ASTNode funcNode = createASTNodeTree(context, root.getChild(3));\n      if (Type.isDivergentTo(funcNode.getReturnType(), Type.LONG)) {\n        throw new SemanticCheckFailure(\n            String.format(\n                \"Sort is expected to return %s but passed function returns %s\",\n                Type.LONG,\n                funcNode.getReturnType()));\n      }\n\n      context.removeScope();\n\n      ASTNode result = Sort.toSort(\n          exprText, varA, varB, funcNode, context.currentScopeId(), collectionNode);\n      return result;\n    } else if (root.getChildCount() == 2) {\n      ASTNode collectionNode = createASTNodeTree(context, root.getChild(1));\n      Type elementType = Type.OBJECT;\n      if (Collection.class.isAssignableFrom(collectionNode.getReturnType().typeBase)) {\n        elementType = collectionNode.getReturnType().getTypeParams().get(0);\n      }\n","sourceCodeStart":999,"sourceCodeEnd":1035,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/botmaker/src/java/com/twitter/botmaker/compiler/Compiler.java#L999-L1035","documentation":"Sort's comparator function must return a Long (numeric ordering key). If the compiled comparator lambda returns any type divergent from Type.LONG, the compiler rejects the Sort expression.","triggerScenarios":"`Sort(coll, fn)` where fn returns Double, String, Boolean, or a struct instead of Long.","commonSituations":"Writing a comparator that returns the result of a string comparison helper, a boolean predicate, or forgetting to coerce a numeric computation to a long.","solutions":["Make the comparator return a Long (wrap comparisons in If(...) producing 0L/1L, or cast with ToLong)","If sorting by an object key, compute a numeric sort key inside the lambda"],"exampleFix":"// before\nSort(users, (a, b) -> a.name < b.name)\n// after\nSort(users, (a, b) -> If(a.name < b.name, -1L, 1L))","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// validate comparator returns Long before compiling Sort\nif (!LONG.equals(comparatorReturnType)) throw new IllegalArgumentException(\"Sort comparator must return Long\");","tryCatchPattern":"catch (SemanticCheckFailure e) { if (e.getMessage().contains(\"Sort is expected\")) surfaceTypeHint(e); else throw e; }","preventionTips":["Always make comparators yield -1L/0L/1L or numeric long keys"],"tags":["botmaker","sort","type-mismatch","comparator"],"backgroundTag":"comparator-return-type","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}