← Back to Kontasks
Fixed: gvDecision Stats 404 Bug
Route ordering bug fix for konui_get_decision_stats
Output
✓ Fixed: gvDecision Stats 404 Bug
✓ Bug fixed and verified working!
Root Cause
The route /api/gv/decisions/stats was being intercepted by the single decision GET route:
// This regex matched "stats" as an ID const match = path.match(/^\/api\/gv\/decisions\/([^/]+)$/); // "stats" matches [^/]+ → tried to find decision "stats" → 404
Fix Applied
Moved the /api/gv/decisions/stats route before the single decision route:
// Get decision stats (MUST be before single decision route) if (path === "/api/gv/decisions/stats" && method === "GET") { const stats = await gvDecisionStore.getDecisionStats(); return jsonResponse({ stats }); } // Get single decision (now checked after stats) const decisionIdMatch = path.match(...);
Verification
✓ konui_get_decision_stats now returns: total: 1 design: 1 action: 0 deferred: 0 pending: 1
Commit
1d96111b Fix: Route order for gvDecision stats endpoint File: konui/src/router.ts (+6/-6)
💡 Lesson: When using regex routes like
/resource/:id, always define literal routes (like /resource/stats) first to prevent unintended matches.
Quick Actions
Original Request
No layout configured
Details
Type
General
Status
Completed
Scope
vibetools
Tags
bugfixgvdecisionsrouter
Created
9 Jan 2026, 6:48 pm
Updated
9 Jan 2026, 6:48 pm
Created By
claude
📋 Claude's Context
Session
ses_9c69cb59...
Raw Data
{
"id": "e0756878-b2b5-4e2d-a5e7-f763a967dcf8",
"type": "general",
"status": "completed",
"title": "Fixed: gvDecision Stats 404 Bug",
"description": "Route ordering bug fix for konui_get_decision_stats",
"context": {
"output": "<div style=\"background:#1e1e1e;color:#e0e0e0;padding:20px;border-radius:8px;font-family:'Consolas','Monaco',monospace;\">\n<h2 style=\"font-family:sans-serif;color:#fff;margin:0 0 16px 0;\">✓ Fixed: gvDecision Stats 404 Bug</h2>\n\n<div style=\"background:#1a3a1a;border:1px solid #2d5a2d;padding:12px;border-radius:6px;margin-bottom:16px;\">\n<span style=\"color:#98c379;\">✓</span> <strong style=\"color:#98c379;\">Bug fixed and verified working!</strong>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#61afef;margin:0 0 12px 0;\">Root Cause</h3>\n<p style=\"margin:0;line-height:1.6;\">\nThe route <code style=\"background:#1e1e1e;padding:2px 6px;border-radius:3px;\">/api/gv/decisions/stats</code> was being intercepted by the single decision GET route:\n</p>\n<pre style=\"margin:12px 0 0 0;line-height:1.6;background:#1e1e1e;padding:12px;border-radius:4px;\">\n<span style=\"color:#7f848e;\">// This regex matched \"stats\" as an ID</span>\n<span style=\"color:#c678dd;\">const</span> match = path.match(<span style=\"color:#98c379;\">/^\\/api\\/gv\\/decisions\\/([^/]+)$/</span>);\n<span style=\"color:#7f848e;\">// \"stats\" matches [^/]+ → tried to find decision \"stats\" → 404</span>\n</pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#61afef;margin:0 0 12px 0;\">Fix Applied</h3>\n<p style=\"margin:0;line-height:1.6;\">\nMoved the <code style=\"background:#1e1e1e;padding:2px 6px;border-radius:3px;\">/api/gv/decisions/stats</code> route <strong>before</strong> the single decision route:\n</p>\n<pre style=\"margin:12px 0 0 0;line-height:1.6;background:#1e1e1e;padding:12px;border-radius:4px;font-size:12px;\">\n<span style=\"color:#7f848e;\">// Get decision stats (MUST be before single decision route)</span>\n<span style=\"color:#c678dd;\">if</span> (path === <span style=\"color:#98c379;\">\"/api/gv/decisions/stats\"</span> && method === <span style=\"color:#98c379;\">\"GET\"</span>) {\n <span style=\"color:#c678dd;\">const</span> stats = <span style=\"color:#c678dd;\">await</span> gvDecisionStore.getDecisionStats();\n <span style=\"color:#c678dd;\">return</span> jsonResponse({ stats });\n}\n\n<span style=\"color:#7f848e;\">// Get single decision (now checked after stats)</span>\n<span style=\"color:#c678dd;\">const</span> decisionIdMatch = path.match(...);\n</pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#61afef;margin:0 0 12px 0;\">Verification</h3>\n<pre style=\"margin:0;line-height:1.8;\">\n<span style=\"color:#98c379;\">✓</span> konui_get_decision_stats now returns:\n <span style=\"color:#7f848e;\">total:</span> <span style=\"color:#e5c07b;\">1</span>\n <span style=\"color:#7f848e;\">design:</span> <span style=\"color:#e5c07b;\">1</span>\n <span style=\"color:#7f848e;\">action:</span> <span style=\"color:#e5c07b;\">0</span>\n <span style=\"color:#7f848e;\">deferred:</span> <span style=\"color:#e5c07b;\">0</span>\n <span style=\"color:#7f848e;\">pending:</span> <span style=\"color:#e5c07b;\">1</span>\n</pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:16px;border-radius:6px;margin-bottom:16px;\">\n<h3 style=\"color:#61afef;margin:0 0 12px 0;\">Commit</h3>\n<pre style=\"margin:0;line-height:1.6;\">\n<span style=\"color:#e5c07b;\">1d96111b</span> <span style=\"color:#98c379;\">Fix: Route order for gvDecision stats endpoint</span>\n<span style=\"color:#7f848e;\">File:</span> <span style=\"color:#c678dd;\">konui/src/router.ts</span> <span style=\"color:#7f848e;\">(+6/-6)</span>\n</pre>\n</div>\n\n<div style=\"background:#1a3a1a;border:1px solid #2d5a2d;padding:12px;border-radius:6px;\">\n<span style=\"color:#98c379;\">💡</span> <strong style=\"color:#98c379;\">Lesson:</strong> When using regex routes like <code style=\"background:#1e1e1e;padding:2px 6px;border-radius:3px;\">/resource/:id</code>, always define literal routes (like <code style=\"background:#1e1e1e;padding:2px 6px;border-radius:3px;\">/resource/stats</code>) first to prevent unintended matches.\n</div>\n</div>",
"requestedAt": "2026-01-09T08:47:00.000Z",
"requestId": "185ea9b4-5ada-443e-b0f1-7578f13c04b8",
"choices": [
{
"label": "Push commit",
"value": "Push the fix commit to origin",
"primary": true
},
{
"label": "View all stats",
"value": "Show me the full decision and flow stats"
}
]
},
"createdBy": "claude",
"createdAt": "2026-01-09T08:48:31.646Z",
"updatedAt": "2026-01-09T08:48:31.876Z",
"requestId": "185ea9b4-5ada-443e-b0f1-7578f13c04b8",
"scope": "vibetools",
"tags": [
"bugfix",
"gvdecisions",
"router"
],
"sessionId": "ses_9c69cb59-31c",
"flowId": "flow_01KEGVRXHHK7E25VFSX4HCV289",
"flowLinks": [
{
"flowId": "flow_01KEGVRXHHK7E25VFSX4HCV289",
"edgeType": "evidence",
"createdAt": "2026-01-09T08:48:31.646Z"
}
],
"targetUser": "claude"
}