# Fibery MCP Server: q\_where Clause Format Mismatch Causes API Error

**URL:** <https://community.fibery.io/t/fibery-mcp-server-q-where-clause-format-mismatch-causes-api-error/9394>\
**Category:** Bugs & Issues\
**Tags:** ai\
**Created:** [August 10, 2025, 11:05am UTC](https://community.fibery.io/t/fibery-mcp-server-q-where-clause-format-mismatch-causes-api-error/9394 "2025-08-10T11:05:14Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yuri\_BC](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/yuri_bc/32/8803_2.png) [@Yuri\_BC](https://community.fibery.io/u/Yuri_BC)\
**Post date:** [August 10, 2025, 11:05am UTC](https://community.fibery.io/t/fibery-mcp-server-q-where-clause-format-mismatch-causes-api-error/9394/1 "2025-08-10T11:05:14Z")

</div>

While working with the Fibery MCP server, I encountered a recurring issue where queries fail with a validation error if the `q_where` parameter is provided in array form instead of the expected object form.

Currently, this seems to require manual correction in client-side code or tooling prompts. To make integrations more resilient and reduce friction for developers, it would be helpful if the MCP server automatically normalized array-style `q_where` clauses to the object format before validation.

Below are the technical details and a reproducible example of the issue, along with a suggested fix.

**Summary**  
Some clients generate `q_where` as an array (e.g., `["=", ["fibery/public-id"], "$id"]`). The server validator requires an object (e.g., `{ "=": [["fibery/public-id"], "$id"] }`) and returns:  
`Input validation error: [...] is not of type 'object'`.

**Expected behavior**  
Accept array-form `q_where` or normalize it to the object form server-side before validation/execution.

**Actual behavior**  
Requests fail when `q_where` is an array at the top level, despite being semantically correct.

**Minimal reproduction (generic)**

```auto
{
  "q_from": "Space/Entity",
  "q_select": { "Name": ["Space/Name"] },
  "q_where": ["=", ["fibery/public-id"], "$publicId"],
  "q_limit": 1,
  "q_params": { "$publicId": "1" }
}

```

**Proposed fix (server-side normalization)**  
Normalize `q_where` if it arrives in array form; keep object form untouched; reject other types clearly.

TypeScript/Node (if the server or proxy is JS-based)

```auto
type JSONVal = any;

function normalizeWhere(node: JSONVal): JSONVal {
  if (node && typeof node === "object" && !Array.isArray(node)) return node; // already object-form
  if (Array.isArray(node)) {
    if (node.length === 0) throw new Error("Invalid q_where: empty array");
    const op = node[0];
    if (op === "q/and" || op === "q/or") {
      return { [op]: node.slice(1).map(normalizeWhere) }; // recursively normalize children
    }
    return { [op]: node.slice(1) }; // e.g., "=","!=","<",">=", "q/in", etc.
  }
  throw new Error("Invalid q_where: must be array or object");
}

export function preprocessFiberyQueryDatabase(params: Record<string, JSONVal>) {
  if (params && "q_where" in params) params.q_where = normalizeWhere(params.q_where);
  return params;
}

```

Python (if the server is Python-based)

```auto
from typing import Any, Dict, List, Union

JSON = Union[Dict[str, Any], List[Any], str, int, float, bool, None]

def normalize_where(node: JSON) -> JSON:
    if isinstance(node, dict):
        return node # already object-form
    if isinstance(node, list):
        if not node:
            raise ValueError("Invalid q_where: empty array")
        op, *rest = node
        if op in ("q/and", "q/or"):
            return {op: [normalize_where(x) for x in rest]}
        return {op: rest}
    raise ValueError("Invalid q_where: must be array or object")

def preprocess_params(params: Dict[str, Any]) -> Dict[str, Any]:
    if "q_where" in params:
        params["q_where"] = normalize_where(params["q_where"])
    return params

```

Normalization rules (concise)

1. If `q_where` is an object, leave it.

2. If `q_where` is an array:  
• `["q/and", cond1, cond2, ...]` → `{ "q/and": [normalize(cond1), normalize(cond2), ...] }`  
• `["=", fieldPath, value]` → `{ "=": [fieldPath, value] }` (works for `!=`, `<`, `<=`, `>`, `>=`, `q/in`, `q/not-in`, etc.)

3. If `q_where` is empty array, or neither array nor object, reject with a clear message.

Test cases

- Single condition: `["=", ["fibery/public-id"], "$id"]` → `{ "=": [["fibery/public-id"], "$id"] }`

- Nested AND: `["q/and", ["=", ["A/Name"], "$n"], [">", ["fibery/creation-date"], "$after"]]` → `{ "q/and": [{ "=": [["A/Name"], "$n"] }, { ">": [["fibery/creation-date"], "$after"] }] }`

- Already object: unchanged.

- Invalid types: explicit error.

**Impact**  
This server-side normalization makes all clients resilient (AIs, scripts, integrations) without requiring per-client prompt discipline or brittle runtime workarounds.
