Skip to content

[BUG]: Gateway tags return empty due to type mismatch between schema and validation layer #2563

@childrenofaqsa

Description

@childrenofaqsa

🐞 Bug Summary

Update Gateway and Get Gateway APIs return an empty tags list ([]) even though tags are present in the Postgres gateways.tags JSON column.


🧩 Affected Component

Select the area of the project impacted:

  • mcpgateway - API
  • mcpgateway - UI (admin panel)
  • mcpgateway.wrapper - stdio wrapper
  • Federation or Transports
  • CLI, Makefiles, or shell scripts
  • Container setup (Docker/Podman/Compose)
  • Other (explain below)

🔁 Steps to Reproduce

  1. Create a Gateway with tags via API (e.g., POST /gateways) using tags: ["Finance", "ml"].
  2. Verify tags exist in Postgres for that gateway (e.g., SELECT tags FROM gateways WHERE id = '<gateway_id>';) and confirm the JSON contains tag values.
  3. Update the same Gateway via API (e.g., PUT /gateways/{gateway_id}) and include tags: ["Finance", "ml"] (or update any other field—either way, tags remain present in DB).
  4. Observe the response tags is [] even though the DB row still contains tags.
  5. Call GET /gateways/{gateway_id} again
  6. Observe the response tags is [] even though the DB row still contains tags.

🤔 Expected Behavior

If tags exist in the database for a gateway, GET /gateways/{gateway_id} (and the response from PATCH/PUT /gateways/{gateway_id}) should return those tags rather than an empty list.


📓 Logs / Error Output

Example response (200 OK) showing empty tags:

{
  "id": "<gateway_id>",
  "name": "my-gateway",
  "tags": []
}

🧠 Environment Info

You can retrieve most of this from the /version endpoint.

Key Value
Version or commit 1.0.0-BETA-1
Runtime Python 3.13
Platform / OS Windows 11
Container none
Database Postgres

🧩 Additional Context (optional)

Tag normalization/validation converts every tag element to a string first (including non-string JSON items), which can cause stored tag objects / stringified dicts to normalize into invalid formats and be filtered out—resulting in [] even when the DB contains data. See TagValidator.validate_list() stringification at

if not tags:
return []
# Filter out None values and convert everything to strings
string_tags = [str(tag) for tag in tags if tag is not None]
# Normalize all tags while preserving the original input for the label
normalized_pairs: List[tuple[str, str]] = []
for tag in string_tags:
# Skip empty strings or strings with only whitespace
if tag and tag.strip():
original = tag.strip()
normalized = TagValidator.normalize(original)
normalized_pairs.append((normalized, original))

Metadata

Metadata

Assignees

Labels

SHOULDP2: Important but not vital; high-value items that are not crucial for the immediate releasebugSomething isn't workingpythonPython / backend development (FastAPI)

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions