GoogleBigQueryTools._run_sql() corrupts SQL queries with comments due to newline removal

Summary

GoogleBigQueryTools._run_sql() removes newline characters without preserving token boundaries, causing SQL line comments (–) to swallow the entire query. The silent error handler then returns an empty string, making failures appear as “0 rows returned.”

Affected Version

  • Agno v2.x (tested on v2.3.x)

  • File: agno/tools/google_bigquery.py, line 109

Root Cause

# Line 109 - current implementation

cleaned_query = sql.replace("\\n", " ").replace("\n", "").replace("\\", "")

The .replace(“\n”, “”) removes actual newlines without adding spaces. This breaks SQL line comments (–) which extend until the next newline character.

Reproduction Steps

  1. Create an agent with GoogleBigQueryTools

  2. Have the agent generate a query with a – comment:

query = """SELECT 

    p.product_id,

    SUM(o.amount) AS revenue,

    -- Calculate net after discounts

    SUM(o.amount) - SUM(o.discount) AS net_revenue

FROM orders o

JOIN products p ON o.product_id = p.product_id

LIMIT 10"""
  1. Call run_sql_query(query)

Expected Behaviour

Query executes successfully, returning results.

Actual Behaviour

After _run_sql() processing, the query becomes:

SELECT p.product_id, SUM(o.amount) AS revenue, -- Calculate net after discounts SUM(o.amount) - SUM(o.discount) AS net_revenueFROM orders oJOIN products p ON o.product_id = p.product_idLIMIT 10

The – comment now extends to the end of the (single-line) query, commenting out:

  • SUM(o.amount) - SUM(o.discount) AS net_revenue

  • FROM orders o

  • JOIN products p ON o.product_id = p.product_id

  • LIMIT 10

BigQuery receives an incomplete SELECT statement → syntax error → exception caught → returns .

Secondary Issues

1. Silent Error Handler (Lines 115-117)

except Exception as e:

    logger.error(f"Error while executing SQL: {e}")

    return ""  # Returns empty string, not error message

Agents interpret “” as “query returned 0 rows” rather than “query failed.”

2. Double Serialization (Lines 95 + 113-114)

# _run_sql() returns a string:

results_str = str([dict(row) for row in results])

return results_str

# run_sql_query() JSON-encodes that string:

return json.dumps(self._run_sql(sql=query), default=str)

This creates double-encoded output that may confuse LLM parsing.

Proposed Fix

# Line 109 - replace newlines with SPACES, not empty string

cleaned_query = sql.replace("\\n", " ").replace("\n", " ").replace("\\", "")

#                                                      ↑ SPACE instead of ""

# Lines 115-117 - return error message, not empty string

except Exception as e:

    logger.error(f"Error while executing SQL: {e}")

    return f"Error executing query: {e}"

Impact

  • Severity: High - Any query with SQL comments silently fails

Hi @shubham, thank you for reaching out and supporting Agno. I’ve shared this with the team, we’re working through all queries one by one and will get back to you soon. If it’s urgent, please let us know. We appreciate your patience!

Thanks for your reply @yuvi . Yes this seems like a blocker to my analyst agent. Let me know if there is a workaround or the proposed fix is correct.

Hey @shubham, thanks for reporting this. You are right that our parsing logic GoogleBigQueryTools is defective.

We have a fix for this already: fix: GoogleBigQueryTools SQL statements parsing by manuhortet · Pull Request #5957 · agno-agi/agno · GitHub

I’ll make sure we deliver it as part of our next version, later today or very early next week.