Skip to content

fix query route safe clickhouse error codes#1268

Merged
BilalG1 merged 4 commits intodevfrom
fix-query-route-safe-codes
Mar 23, 2026
Merged

fix query route safe clickhouse error codes#1268
BilalG1 merged 4 commits intodevfrom
fix-query-route-safe-codes

Conversation

@BilalG1
Copy link
Copy Markdown
Collaborator

@BilalG1 BilalG1 commented Mar 18, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Refined analytics query error classification so certain database errors are treated as known/handled, reducing exposure of internal diagnostics in responses.
  • Tests

    • Added end-to-end tests verifying safe (masked) error responses, preventing leakage of restricted column/identifier details and constraining suggestion text in error messages.

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stack-auth-hosted-components Ready Ready Preview, Comment Mar 23, 2026 5:07pm
stack-backend Ready Ready Preview, Comment Mar 23, 2026 5:07pm
stack-dashboard Ready Ready Preview, Comment Mar 23, 2026 5:07pm
stack-demo Ready Ready Preview, Comment Mar 23, 2026 5:07pm
stack-docs Ready Ready Preview, Comment Mar 23, 2026 5:07pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 18, 2026

📝 Walkthrough

Walkthrough

Updates ClickHouse error classification by marking codes 43 and 47 as unsafe for analytics query handling and adds end-to-end tests covering ILLEGAL_TYPE_OF_ARGUMENT and UNKNOWN_IDENTIFIER error cases. No exported signatures changed.

Changes

Cohort / File(s) Summary
Analytics route change
apps/backend/src/app/api/latest/internal/analytics/query/route.ts
Marked ClickHouse error codes 43 and 47 as unsafe in the error classification used by getSafeClickhouseErrorMessage, altering which original ClickHouse messages are treated as known unsafe errors.
E2E tests
apps/e2e/tests/backend/endpoints/api/v1/analytics-query.test.ts
Added three end-to-end tests validating API responses and masked diagnostic content for: ILLEGAL_TYPE_OF_ARGUMENT (SELECT arrayJoin(123) / code 43), a restricted-column type-check failure (SELECT arrayJoin(query) FROM system.query_log), and UNKNOWN_IDENTIFIER (SELECT qurey FROM system.query_log / code 47). Tests assert response shape, headers, and snapshots (query_id stripped).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through code with a curious nose,
Two numbers found where the wild query goes,
One squeaked and one hid beneath the grass,
Tests twitched their whiskers, then let it pass,
A gentle hop — the meadow's safe at last.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description contains only a template comment without any actual code-level explanation of the changes made. Add a detailed description explaining why codes 43 and 47 are now treated as safe, the security/behavior implications, and reference the related test additions.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change: adding error codes 43 and 47 to the unsafe ClickHouse error codes list in the query route.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-query-route-safe-codes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 18, 2026

Greptile Summary

This PR expands the set of "safe" ClickHouse error codes in the internal analytics query route by adding codes 43 (ILLEGAL_TYPE_OF_ARGUMENT) and 47 (UNKNOWN_IDENTIFIER). When a query fails with one of these codes, the raw ClickHouse error message is now returned to the caller instead of the opaque fallback string "Error during execution of this query.", improving debuggability for admin users writing analytic queries.

Key observations:

  • Both new codes represent user-query errors (bad argument types, referencing non-existent identifiers), which is the correct category of errors to surface directly to callers.
  • The endpoint is already admin-only (adminAuthTypeSchema), so exposing detailed error messages carries low risk.
  • A minor consideration: ClickHouse error 47 (UNKNOWN_IDENTIFIER) can sometimes append schema hints such as "did you mean: <column>?" in its message. For an internal admin route this is acceptable, but worth being aware of if the surface area ever broadens.
  • The handler continues to use createSmartRouteHandler, consistent with the project's routing conventions.

Confidence Score: 4/5

  • This PR is safe to merge; it makes a minimal, well-scoped change to a single constant array on an admin-only internal endpoint.
  • The change is small (two lines added to a constant array), touches no business logic, and the new error codes (43, 47) are both user-query errors that are appropriate to surface verbatim. The only minor concern is that ClickHouse error 47 messages can occasionally include schema suggestions, but the endpoint is restricted to admin users, making information disclosure risk negligible.
  • No files require special attention.

Important Files Changed

Filename Overview
apps/backend/src/app/api/latest/internal/analytics/query/route.ts Adds error codes 43 (ILLEGAL_TYPE_OF_ARGUMENT) and 47 (UNKNOWN_IDENTIFIER) to SAFE_CLICKHOUSE_ERROR_CODES, so these user-caused query errors return the raw ClickHouse message instead of the generic fallback. Minor concern: code 47 error messages can sometimes include schema hints (e.g., "did you mean X?"), though the risk is low on this admin-only endpoint.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[POST /analytics/query] --> B[Execute ClickHouse Query]
    B -->|Success| C[Return rows + query_id]
    B -->|Error| D[getSafeClickhouseErrorMessage]
    D --> E{Is error code in\nSAFE_CODES?}
    E -->|Yes - codes 43,47,62,\n159,164,158,396,636| F[Return raw ClickHouse message]
    E -->|No| G{Is error code in\nUNSAFE_CODES?}
    G -->|Yes - codes 36,60,497| H[Return generic message]
    G -->|No - unknown code| I[captureError + generic message]
    H --> J[Throw KnownErrors.AnalyticsQueryError]
    F --> J
    I --> J
Loading

Last reviewed commit: "fix query route safe..."

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/e2e/tests/backend/endpoints/api/v1/analytics-query.test.ts (1)

1548-1579: Consider adding an explicit production-path masking assertion for code 47.

This test currently validates development-mode output. A focused follow-up test for production-mode behavior would lock in the key security guarantee (generic masked error for unsafe codes).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/e2e/tests/backend/endpoints/api/v1/analytics-query.test.ts` around lines
1548 - 1579, Add a sibling test to "does not leak column names from restricted
tables via unknown identifier (code 47)" that invokes runQuery (or the same test
helper) with production-mode semantics and asserts the response is a generic
masked ANALYTICS_QUERY_ERROR without the ClickHouse suggestion text ("Maybe you
meant" or real column names); use the same query ("SELECT qurey FROM
system.query_log"), reuse stripQueryId(expect) for normalization, and assert the
body.error/body.details do not contain "Maybe you meant" or "query" but instead
contain the generic masked message expected in production.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/e2e/tests/backend/endpoints/api/v1/analytics-query.test.ts`:
- Around line 1548-1579: Add a sibling test to "does not leak column names from
restricted tables via unknown identifier (code 47)" that invokes runQuery (or
the same test helper) with production-mode semantics and asserts the response is
a generic masked ANALYTICS_QUERY_ERROR without the ClickHouse suggestion text
("Maybe you meant" or real column names); use the same query ("SELECT qurey FROM
system.query_log"), reuse stripQueryId(expect) for normalization, and assert the
body.error/body.details do not contain "Maybe you meant" or "query" but instead
contain the generic masked message expected in production.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 90f3ba1a-6841-457a-b188-0eed9f3f1b33

📥 Commits

Reviewing files that changed from the base of the PR and between e12e49d and 35fe4a4.

📒 Files selected for processing (2)
  • apps/backend/src/app/api/latest/internal/analytics/query/route.ts
  • apps/e2e/tests/backend/endpoints/api/v1/analytics-query.test.ts

@BilalG1 BilalG1 requested a review from N2D4 March 18, 2026 22:30
@BilalG1 BilalG1 assigned N2D4 and unassigned BilalG1 Mar 18, 2026
Comment thread apps/e2e/tests/backend/endpoints/api/v1/analytics-query.test.ts
@github-actions github-actions Bot assigned BilalG1 and unassigned N2D4 Mar 21, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/e2e/tests/backend/endpoints/api/v1/analytics-query.test.ts (1)

1558-1622: Add one production-path assertion for the no-leak guarantee.

These cases currently assert test-mode behavior (which still includes full ClickHouse text). Please add a production-mode assertion (or a route-level unit test around getSafeClickhouseErrorMessage) verifying codes 43/47 return only the default sanitized message and do not include query/table/column details.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/e2e/tests/backend/endpoints/api/v1/analytics-query.test.ts` around lines
1558 - 1622, Tests assert development-mode ClickHouse error text leakage for
codes 43 and 47 but lack a production-path assertion that
getSafeClickhouseErrorMessage sanitizes those errors; add a new assertion that
simulates production mode (or calls getSafeClickhouseErrorMessage directly) for
the two cases (arrayJoin/code 43 and unknown identifier/code 47) and verify the
returned message is the default sanitized message without any query/table/column
details, referencing the test cases in analytics-query.test.ts and the helper
function getSafeClickhouseErrorMessage to locate where to add the
production-mode check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/e2e/tests/backend/endpoints/api/v1/analytics-query.test.ts`:
- Around line 1558-1622: Tests assert development-mode ClickHouse error text
leakage for codes 43 and 47 but lack a production-path assertion that
getSafeClickhouseErrorMessage sanitizes those errors; add a new assertion that
simulates production mode (or calls getSafeClickhouseErrorMessage directly) for
the two cases (arrayJoin/code 43 and unknown identifier/code 47) and verify the
returned message is the default sanitized message without any query/table/column
details, referencing the test cases in analytics-query.test.ts and the helper
function getSafeClickhouseErrorMessage to locate where to add the
production-mode check.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9b7be848-901a-4bd7-b58e-58c5ed340a52

📥 Commits

Reviewing files that changed from the base of the PR and between 35fe4a4 and a2ffeee.

📒 Files selected for processing (2)
  • apps/backend/src/app/api/latest/internal/analytics/query/route.ts
  • apps/e2e/tests/backend/endpoints/api/v1/analytics-query.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/backend/src/app/api/latest/internal/analytics/query/route.ts

@BilalG1 BilalG1 merged commit 381e057 into dev Mar 23, 2026
32 checks passed
@BilalG1 BilalG1 deleted the fix-query-route-safe-codes branch March 23, 2026 17:30
@coderabbitai coderabbitai Bot mentioned this pull request Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants