Zie619/n8n-workflows · error · HTTPException

Error searching by category: {str(e)}

Error message

Error searching by category: {str(e)}

What it means

A generic 500 from GET /api/workflows/category/{category}. After computing workflow_summaries, total, and pages, any exception in the search/aggregation path is wrapped as 'Error searching by category: {str(e)}'. Causes live in the category search implementation called above the shown region (DB query, category normalization, or pagination math).

Source

Thrown at api_server.py:745

            except Exception as e:
                print(
                    f"Error converting workflow {workflow.get('filename', 'unknown')}: {e}"
                )
                continue

        pages = (total + per_page - 1) // per_page

        return SearchResponse(
            workflows=workflow_summaries,
            total=total,
            page=page,
            per_page=per_page,
            pages=pages,
            query=f"category:{category}",
            filters={"category": category},
        )
    except Exception as e:
        raise HTTPException(
            status_code=500, detail=f"Error searching by category: {str(e)}"
        )


# Custom exception handler for better error responses
@app.exception_handler(Exception)
async def global_exception_handler(request, exc):
    return JSONResponse(
        status_code=500, content={"detail": f"Internal server error: {str(exc)}"}
    )


# Mount static files AFTER all routes are defined
static_dir = Path("static")
if static_dir.exists():
    app.mount("/static", StaticFiles(directory="static"), name="static")
    print(f"✅ Static files mounted from {static_dir.absolute()}")
else:

View on GitHub (pinned to 94007c1445)

Solutions

  1. Reproduce with the exact category string and read the appended str(e) in the response body — it identifies the failing query/operation.
  2. Run the reindex (POST /api/reindex with a valid admin token, or the CLI indexer) so category tables/rows exist.
  3. Verify the category slug is one returned by GET /api/categories; use those exact values.
  4. If the error persists, inspect the category-search helper above this handler for schema mismatches with your DB version.
Defensive patterns

Strategy: try-catch

Validate before calling

valid_categories = set(client.get("/api/categories").json()["categories"])

def category_exists(category: str) -> bool:
    return category in valid_categories

Try / catch

try:
    resp = client.get(f"/api/workflows/category/{category}", params={"page": 1, "per_page": 20})
    resp.raise_for_status()
except HTTPError as e:
    if e.response.status_code == 500 and "Error searching by category" in e.response.text:
        # log detail (contains root cause) and surface an empty page to the UI
        page_data = {"workflows": [], "total": 0, "page": 1, "per_page": 20, "pages": 0}
    else:
        raise

Prevention

When it happens

Trigger: GET /api/workflows/category/messaging (or any category slug) with a valid page/per_page while the underlying DB category index is missing or the category search helper raises — e.g. no such table/column, or a None row breaking summary construction. URL-encoded slashes or unknown categories typically flow through the search, not this 500.

Common situations: DB never indexed after a fresh deploy; category column renamed in a newer schema while the search query still uses the old name; very large per_page combined with a buggy row-mapping loop; SQLite lock during concurrent reindex.

Related errors


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