{"record":{"id":"0ccfade67ceb0e9a","repo":"plandex-ai/plandex","slug":"no-project-ids-provided","errorCode":null,"errorMessage":"No project ids provided","messagePattern":"No project ids provided","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"app/server/handlers/plans_crud.go","lineNumber":417,"sourceCode":"\n\twritePlans()\n}\n\nfunc ListPlansRunningHandler(w http.ResponseWriter, r *http.Request) {\n\tlog.Println(\"Received request for ListPlansRunningHandler\")\n\tauth := Authenticate(w, r, true)\n\tif auth == nil {\n\t\treturn\n\t}\n\n\tprojectIds := r.URL.Query()[\"projectId\"]\n\tincludeRecent := r.URL.Query().Get(\"recent\") == \"true\"\n\n\tlog.Println(\"projectIds: \", projectIds)\n\n\tif len(projectIds) == 0 {\n\t\tlog.Println(\"No project ids provided\")\n\t\thttp.Error(w, \"No project ids provided\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tfor _, projectId := range projectIds {\n\t\tif !authorizeProject(w, projectId, auth) {\n\t\t\treturn\n\t\t}\n\t}\n\n\tplans, err := db.ListOwnedPlans(projectIds, auth.User.Id, false)\n\n\tif err != nil {\n\t\tlog.Printf(\"Error listing plans: %v\\n\", err)\n\t\thttp.Error(w, \"Error listing plans: \"+err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tvar planIds []string","sourceCodeStart":399,"sourceCodeEnd":435,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/plans_crud.go#L399-L435","documentation":"ListPlansRunningHandler (plans_crud.go:417) returns 400 'No project ids provided' when the request has no projectId query parameters. Unlike ListPlansHandler (which returns an empty list), this handler requires at least one projectId because it lists currently running plans, so an empty filter is treated as a client error.","triggerScenarios":"GET the running-plans endpoint with no ?projectId=... parameter, an empty projectId value (e.g. ?projectId= yields no values via r.URL.Query()[\"projectId\"] semantics), or a client sending the parameter under a misspelled/wrong key.","commonSituations":"Client code builds the URL without appending project IDs; a UI sends ?projectId= (empty value) instead of omitting it or repeating the key; SDK/client version mismatch changing the query parameter name.","solutions":["Add at least one projectId query parameter: GET .../plans/running?projectId=<id> (repeat the key for multiple projects).","Check the client sends the exact parameter name 'projectId' (case-sensitive).","If the value may be empty, omit the parameter or filter out empty strings client-side before the request.","Ensure project IDs are loaded/fetched before calling this endpoint."],"exampleFix":"// before\nconst url = `/api/plans/running?projectId=`; // empty value\n// after\nconst ids = projectIds.filter(Boolean).map(id => `projectId=${encodeURIComponent(id)}`).join('&');\nconst url = `/api/plans/running?${ids}`;","handlingStrategy":"validation","validationCode":"const ids = (projectIds || []).filter(Boolean);\nif (ids.length === 0) throw new Error('At least one projectId is required for the running-plans endpoint');\nconst url = `/api/plans/running?${ids.map(id => `projectId=${encodeURIComponent(id)}`).join('&')}`;","typeGuard":"function hasProjectIds(params) {\n  return Array.isArray(params.projectId) ? params.projectId.filter(Boolean).length > 0 : Boolean(params.projectId);\n}","tryCatchPattern":"const res = await fetch(url);\nif (res.status === 400 && (await res.text()).includes('No project ids provided')) {\n  // caller bug: send at least one projectId before retrying\n  return [];\n}\nif (!res.ok) throw new Error(`running plans request failed: ${res.status}`);","preventionTips":["Always append at least one non-empty projectId query parameter.","Filter empty strings out of project ID lists before building the URL.","Use the exact case-sensitive parameter name projectId.","Validate required inputs client-side before calling endpoints that reject empty filters."],"tags":["http-400","validation","go","query-params"],"backgroundTag":"missing-required-argument","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}