{"record":{"id":"5bdbf749f3ae3021","repo":"apache/shardingsphere","slug":"object-types-must-be-an-array","errorCode":null,"errorMessage":"object_types must be an array.","messagePattern":"object_types must be an array\\.","errorType":"validation","errorClass":"MCPInvalidRequestException","httpStatus":null,"severity":"error","filePath":"mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/request/MCPToolArguments.java","lineNumber":56,"sourceCode":"@RequiredArgsConstructor\npublic final class MCPToolArguments {\n    \n    private final Map<String, Object> arguments;\n    \n    /**\n     * Get object types.\n     *\n     * @param supportedObjectTypes supported object types\n     * @return object types\n     * @throws MCPInvalidRequestException object types is malformed or unsupported\n     */\n    public Set<SupportedMCPMetadataObjectType> getObjectTypes(final Set<SupportedMCPMetadataObjectType> supportedObjectTypes) {\n        Object rawValue = arguments.get(\"object_types\");\n        if (null == rawValue) {\n            return Collections.emptySet();\n        }\n        if (!(rawValue instanceof Collection)) {\n            throw new MCPInvalidRequestException(\"object_types must be an array.\");\n        }\n        Collection<?> objectTypes = (Collection<?>) rawValue;\n        if (objectTypes.isEmpty()) {\n            return Collections.emptySet();\n        }\n        Set<SupportedMCPMetadataObjectType> result = new LinkedHashSet<>(objectTypes.size(), 1F);\n        for (Object each : objectTypes) {\n            result.add(resolveObjectType(each, supportedObjectTypes));\n        }\n        return result;\n    }\n    \n    private SupportedMCPMetadataObjectType resolveObjectType(final Object objectType, final Set<SupportedMCPMetadataObjectType> supportedObjectTypes) {\n        String actualValue = Objects.toString(objectType, \"\").trim();\n        if (actualValue.isEmpty()) {\n            throw new MCPInvalidRequestException(\"object_types cannot contain blank values.\");\n        }\n        try {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/request/MCPToolArguments.java#L38-L74","documentation":"Thrown by MCPToolArguments.getObjectTypes when the object_types argument is present but is not a JSON array/Collection (e.g. a plain string or number). The metadata tool API expects object_types to be an array of strings; a scalar is treated as a malformed request (MCPInvalidRequestException), not coerced.","triggerScenarios":"arguments.get(\"object_types\") is non-null but not an instanceof Collection — e.g. {\"object_types\": \"table\"} instead of {\"object_types\": [\"table\"]}, or object_types: 5. JSON arrays arrive as List, scalars do not.","commonSituations":"LLM agents collapsing a single-value list into a bare string; clients built from loosely typed maps; passing a comma-joined string \"table,view\" instead of an array.","solutions":["Send object_types as a JSON array of strings: {\"object_types\": [\"table\", \"view\"]}","Split comma-joined values into array elements on the client before sending","Validate the argument shape in your client schema before invoking the tool"],"exampleFix":"// before\nlist_metadata({\"object_types\": \"table\"})\n\n// after\nlist_metadata({\"object_types\": [\"table\"]})","handlingStrategy":"type-guard","validationCode":"Object o = arguments.get(\"object_types\");\nif (o != null && !(o instanceof Collection)) {\n    arguments.put(\"object_types\", o instanceof String s && s.contains(\",\")\n            ? Arrays.asList(s.split(\",\")) : List.of(o));\n}","typeGuard":"// TypeScript — narrow before sending\nfunction isStringArray(v: unknown): v is string[] {\n  return Array.isArray(v) && v.every(x => typeof x === \"string\");\n}\nif (!isStringArray(args.object_types)) args.object_types = [String(args.object_types)];","tryCatchPattern":"try {\n    listMetadata(arguments);\n} catch (MCPInvalidRequestException e) {\n    if (e.getMessage().contains(\"must be an array\")) listMetadata(Map.of(\"object_types\", List.of(String.valueOf(arguments.get(\"object_types\")))));\n}","preventionTips":["Always serialize object_types as a JSON array","Type-check MCP argument payloads against the tool schema client-side"],"tags":["mcp","request-validation","object-types","shardingsphere"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}