xpipe-io/xpipe · error · BeaconClientException

Invalid argument for key " + key

Error message

Invalid argument for key " + key

What it means

McpToolHandler.getStringArgument found the key but the value is either not a JSON string or is a blank string. Required string arguments must be non-blank strings, so the handler rejects any other type.

Source

Thrown at app/src/main/java/io/xpipe/app/beacon/mcp/McpToolHandler.java:94

            if (!(o instanceof String s) || s.isBlank()) {
                return Optional.empty();
            }

            return Optional.of(s);
        }

        public String getStringArgument(String key) throws BeaconClientException {
            if (request.arguments() == null) {
                throw new BeaconClientException("Missing argument for key " + key);
            }

            var o = request.arguments().get(key);
            if (o == null) {
                throw new BeaconClientException("Missing argument for key " + key);
            }

            if (!(o instanceof String s) || s.isBlank()) {
                throw new BeaconClientException("Invalid argument for key " + key);
            }

            return s;
        }

        public Optional<Boolean> getOptionalBooleanArgument(String key) {
            var o = request.arguments().get(key);
            if (o == null) {
                return Optional.empty();
            }

            if (!(o instanceof Boolean b)) {
                return Optional.empty();
            }

            return Optional.of(b);
        }

View on GitHub (pinned to d85ca821ba)

Solutions

  1. Send the argument as a non-empty JSON string
  2. Convert numeric/boolean values to strings client-side before invoking
  3. Use a dedicated typed getter (getBooleanArgument/getOptionalBooleanArgument) for non-string params
  4. Validate types against the tool's inputSchema before the call

Example fix

// before
{"arguments": {"port": 22}}
// after
{"arguments": {"port": "22"}}
Defensive patterns

Strategy: validation

Validate before calling

Object o = toolCall.arguments().get(key);
if (!(o instanceof String s) || s.isBlank()) {
    throw new IllegalArgumentException("'" + key + "' must be a non-blank string");
}

Type guard

static boolean isNonBlankString(Object o) {
    return o instanceof String s && !s.isBlank();
}

Try / catch

try {
    String v = handler.getStringArgument(key);
} catch (BeaconClientException ex) {
    if (ex.getMessage().contains("Invalid argument")) {
        // coerce (String.valueOf) or re-request the value
    } else throw ex;
}

Prevention

When it happens

Trigger: Tool call arguments contain the key with a number, boolean, object, array, or "" (empty/whitespace) value where a non-blank string is required.

Common situations: LLM fills a string parameter with a number (e.g. port 22 instead of "22"); client sends null-like empty string; JSON unquoted value; coerced values from loosely typed clients.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06). Data as JSON: /api/errors/cbee5067514991ec. Report an issue: GitHub.