xai-org/x-algorithm · error · SemanticCheckFailure

Parameter #%d of %s should be %s, received %s instead

Error message

Parameter #%d of %s should be %s, received %s instead

What it means

Each argument to a derived feature call is checked against the declared parameter type; if the argument's return type diverges from the expected type (no implicit coercion), the call is rejected with the 1-based parameter position.

Source

Thrown at botmaker/src/java/com/twitter/botmaker/compiler/Compiler.java:1193

      ImmutableList.Builder<ASTNode> builder = ImmutableList.builder();
      builder.addAll(children);
      for (int i = children.size(); i < params.size(); i++) {
        Tree tree = params.get(i).getThird().get();
        ASTNode child = createASTNodeTree(context, tree);
        builder.add(child);
      }
      args = builder.build();
    }

    List<Pair<String, ASTNode>> variables = Lists.newArrayListWithCapacity(params.size());
    context.addScope();
    for (int i = 0; i < params.size(); i++) {
      String paramName = params.get(i).getSecond();
      Type paramTp =
          TypeCompiler.getType(params.get(i).getFirst(), context.getTypeContext());
      ASTNode arg = args.get(i);
      if (Type.isDivergentTo(paramTp, arg.getReturnType())) {
        throw new SemanticCheckFailure(String.format(
            "Parameter #%d of %s should be %s, received %s instead",
            i + 1, funcName, paramTp, arg.getReturnType()));
      }
      variables.add(Pair.of(paramName, arg));

      context.defineVariable(paramName, paramTp, arg);
    }

    context.addMacro(funcName);
    ASTNode bodyASTNode = context.getCachedDFBody(derivedFeature);
    context.removeMacro(funcName);
    context.removeScope();

    return DerivedFeatureCall.of(derivedFeature, isLogged, lineNo, variables, bodyASTNode);
  }

  private ASTNode toMock(
      CompilerContext context,

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Convert the argument to the declared type (ToLong, ToDouble, ToString, etc.)
  2. Fix the literal form (1L for Long, 1.0 for Double)
  3. Align the call site with the parameter's declared type after signature changes

Example fix

// before
derived feature score(x: Long) = ...
value = score(1.5)
// after
value = score(1L)
Defensive patterns

Strategy: type-guard

Validate before calling

for (i in params) if (Type.isDivergentTo(paramType[i], argType[i])) throw new IllegalArgumentException("Arg " + i + " type mismatch");

Type guard

static boolean argsConform(List<Type> params, List<Type> args) { for (int i=0;i<params.size();i++) if (Type.isDivergentTo(params.get(i), args.get(i))) return false; return true; }

Try / catch

catch (SemanticCheckFailure e) { if (e.getMessage().contains("should be")) surfaceExpectedVsActual(e); else throw e; }

Prevention

When it happens

Trigger: Passing a Double where the parameter is Long, a String where a struct is expected, or null/OBJECT-typed values for a typed parameter.

Common situations: Numeric literals defaulting to the wrong type (e.g. 1.0 vs 1L), passing an untyped feature value (OBJECT) into a typed parameter, or signature type changes not propagated to call sites.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/1ad555827b7c72d9. Report an issue: GitHub.