xai-org/x-algorithm · error · SemanticCheckFailure

Cannot convert nodes to pairs: offset = %d, nodes to convert

Error message

Cannot convert nodes to pairs: offset = %d, nodes to convert = %d (%s)

What it means

Pair-conversion helpers require the remaining nodes (after startOffset) to form complete name/value pairs: the count must be >= startOffset and (n - startOffset) must be even. Odd leftovers or too-few nodes throw SemanticCheckFailure with the offset, node count, and reason ('negative' or 'not even').

Source

Thrown at botmaker/src/java/com/twitter/botmaker/function/conversion/ToPair.java:79

  public static ToPair of(
      String exprText, ASTNode... children) throws SemanticCheckFailure {
    return new ToPair(exprText, ImmutableList.copyOf(children));
  }

  @Override
  @SuppressWarnings("unchecked")  
  protected Object apply(Context<Runtime> context, Object arg1, Object arg2) {
    return new Pair(arg1, arg2);
  }

  public static ImmutableList<ASTNode> convertNodesToPairs(
      ImmutableList<ASTNode> nodes, int startOffset) throws SemanticCheckFailure {
    ImmutableList.Builder<ASTNode> builder = ImmutableList.builder();
    int n = nodes.size();
    if (n < startOffset
        || (n - startOffset) % 2 != 0) {
      throw new SemanticCheckFailure(String.format(
          "Cannot convert nodes to pairs: "
              + "offset = %d, nodes to convert = %d (%s)",
          startOffset - 1,
          n - startOffset,
          n < startOffset ? "negative" : "not even"));
    }
    for (int i = 0; i < startOffset; ++i) {
      builder.add(nodes.get(i));
    }
    for (int i = startOffset; i < n; i += 2) {
      builder.add(new ToPair(
          "ToPair", ImmutableList.of(nodes.get(i), nodes.get(i + 1))));
    }
    return builder.build();
  }
}

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Ensure arguments after the fixed prefix come in name/value pairs — add the missing half
  2. Check for trailing/dangling arguments in the call
  3. When generating code, assert even (args.length - prefix) before emitting

Example fix

// before
Fn(prefix, name1, value1, orphanName)
// after
Fn(prefix, name1, value1, orphanName, orphanValue)
Defensive patterns

Strategy: validation

Validate before calling

// host code before convertNodesToPairs
int rem = nodes.size() - startOffset;
if (nodes.size() < startOffset || rem % 2 != 0) {
  throw new IllegalArgumentException("pair arguments must be even after offset");
}

Prevention

When it happens

Trigger: Calling a function like Fn(name1, value1, name2) — an odd number of pair arguments; or passing fewer nodes than the fixed prefix (e.g. zero pair args where at least one pair is required by offset).

Common situations: Missing the value half of a name: value argument, trailing commas in generated rule text, or off-by-one when building children lists programmatically.

Related errors


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