Zie619/n8n-workflows · error · HTTPException
str(e)
Error message
str(e)
What it means
A generic 500 from POST /integrations/github/sync. The handler calls integration_hub.sync_with_github(repo, token) and wraps any failure as detail=str(e). Note a design flaw: both repo and token are plain query parameters, so the GitHub token lands in access logs and browser history. Failures usually come from GitHub: bad credentials, nonexistent repo, rate limits, or network egress blocked.
Source
Thrown at src/integration_hub.py:257
else:
return {"status": "error", "message": "Webhook endpoint not found"}
# Initialize integration hub
integration_hub = IntegrationHub()
# FastAPI app for Integration Hub
integration_app = FastAPI(title="N8N Integration Hub", version="1.0.0")
@integration_app.post("/integrations/github/sync")
async def sync_github(repo: str, token: str):
"""Sync workflows with GitHub repository."""
try:
result = await integration_hub.sync_with_github(repo, token)
return result
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@integration_app.post("/integrations/slack/notify")
async def notify_slack(webhook_url: str, message: str):
"""Send notification to Slack."""
try:
result = await integration_hub.sync_with_slack(webhook_url, message)
return result
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@integration_app.post("/integrations/discord/notify")
async def notify_discord(webhook_url: str, message: str):
"""Send notification to Discord."""
try:
result = await integration_hub.sync_with_discord(webhook_url, message)
return resultView on GitHub (pinned to 94007c1445)
Solutions
- Test the credential directly: curl -H 'Authorization: Bearer <token>' https://api.github.com/repos/owner/name — a 401/403 there reproduces the server error.
- Use a PAT with at least repo/contents-read scope and confirm it is not expired or SAML-blocked.
- Verify the repo slug format is owner/name and the token's owner can see it.
- Refactor the endpoint to take the token in a header/body instead of a query string, and check server egress to api.github.com.
Example fix
# before
@integration_app.post("/integrations/github/sync")
async def sync_github(repo: str, token: str): # token leaks into access logs
...
# after
from fastapi import Header
@integration_app.post("/integrations/github/sync")
async def sync_github(repo: str, x_github_token: str = Header(...)):
try:
result = await integration_hub.sync_with_github(repo, x_github_token)
return result
except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) Defensive patterns
Strategy: validation
Validate before calling
import re
def github_inputs_ok(repo: str, token: str) -> bool:
return bool(re.fullmatch(r"[\w.-]+/[\w.-]+", repo)) and bool(token) and not token.isspace() Try / catch
try:
result = client.post("/integrations/github/sync", json={"repo": repo, "token": token}).json()
except HTTPError as e:
detail = e.response.text
if "Bad credentials" in detail or "401" in detail:
raise PermissionError("GitHub token rejected — refresh the PAT") from e
if "rate limit" in detail.lower():
# bounded single retry after the reset window, never a tight loop
time.sleep(60)
result = client.post("/integrations/github/sync", json={"repo": repo, "token": token}).json()
else:
raise Prevention
- Verify the PAT with a direct GitHub API call before wiring it into the sync endpoint.
- Never send credentials as query parameters — move the token to a header or request body (server change).
- Give fine-grained PATs exactly the needed scope (Contents: read) and rotate them on a schedule.
- Confirm server egress to api.github.com is open before enabling sync jobs.
When it happens
Trigger: POST /integrations/github/sync?repo=owner/name&token=ghp_xxx with an expired/revoked PAT, insufficient scope (no repo contents read), a repo the token cannot access, or when the server has no outbound network access to api.github.com.
Common situations: Fine-grained PAT missing the 'Contents: read' permission; org SAML enforcement requiring authorization; token pasted with whitespace; self-hosted server behind a firewall blocking GitHub; rate-limited unauthenticated fallback.
Related errors
- Error fetching stats: {str(e)}
- Invalid filename format
- Rate limit exceeded. Please try again later.
- Error loading workflow: {str(e)}
- Access denied
AI-assisted analysis of Zie619/n8n-workflows@94007c1445 (2026-08-15).
Data as JSON: /api/errors/d0b9d31bf0b5388e.
Report an issue: GitHub.