Zie619/n8n-workflows · error · HTTPException

Analytics error: {str(e)}

Error message

Analytics error: {str(e)}

What it means

A generic 500 from the analytics overview endpoint. The handler calls analytics_engine.get_workflow_analytics(), get_trend_analysis(), and get_usage_insights() and packages them into AnalyticsResponse; any exception in those three calls is wrapped as 'Analytics error: {str(e)}'. The analytics engine typically derives its data from a usage-events SQLite DB, so missing tables or empty data are the usual root causes.

Source

Thrown at src/analytics_engine.py:366


@analytics_app.get("/analytics/overview", response_model=AnalyticsResponse)
async def get_analytics_overview():
    """Get comprehensive analytics overview."""
    try:
        analytics_data = analytics_engine.get_workflow_analytics()
        trends = analytics_engine.get_trend_analysis()
        insights = analytics_engine.get_usage_insights()

        return AnalyticsResponse(
            overview=analytics_data["overview"],
            trends=trends,
            patterns=analytics_data["patterns"],
            recommendations=analytics_data["recommendations"],
            generated_at=analytics_data["generated_at"],
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Analytics error: {str(e)}")


@analytics_app.get("/analytics/trends")
async def get_trend_analysis(days: int = Query(30, ge=1, le=365)):
    """Get trend analysis for specified period."""
    try:
        return analytics_engine.get_trend_analysis(days)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Trend analysis error: {str(e)}")


@analytics_app.get("/analytics/insights")
async def get_usage_insights():
    """Get usage insights and patterns."""
    try:
        return analytics_engine.get_usage_insights()
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Insights error: {str(e)}")

View on GitHub (pinned to 94007c1445)

Solutions

  1. Inspect the str(e) in the response detail to identify which of the three engine calls failed.
  2. Initialize/recreate the analytics database (run the engine's init/seed step) so required tables exist.
  3. Confirm the analytics engine's db_path resolves from the server's actual working directory.
  4. If data is simply empty, ensure some usage events were recorded before querying analytics.
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path

def analytics_ready(db_path: str) -> bool:
    import sqlite3
    if not Path(db_path).exists():
        return False
    conn = sqlite3.connect(db_path)
    try:
        tables = {r[0] for r in conn.execute("SELECT name FROM sqlite_master WHERE type='table'")}
        return "usage_events" in tables  # adjust to engine's required table
    finally:
        conn.close()

Try / catch

try:
    overview = client.get("/analytics/").json()
except HTTPError as e:
    if e.response.status_code == 500 and "Analytics error" in e.response.text:
        overview = None  # dashboard degrades to 'no data yet' state
    else:
        raise

Prevention

When it happens

Trigger: GET the analytics overview endpoint when the analytics database has never been initialized (no usage_events table), when timestamp parsing inside trend analysis hits NULL/invalid rows, or when the engine was constructed against a wrong db_path.

Common situations: Fresh install where analytics collection never started; DB file deleted or moved; mixed-era rows after a schema change; the engine reading a path relative to a different cwd.

Related errors


AI-assisted analysis of Zie619/n8n-workflows@94007c1445 (2026-08-15). Data as JSON: /api/errors/634377e452fd860b. Report an issue: GitHub.