{"record":{"id":"793954f5756d8fa6","repo":"chenhg5/cc-connect","slug":"id-is-required","errorCode":null,"errorMessage":"id is required","messagePattern":"id is required","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"core/api.go","lineNumber":715,"sourceCode":"\t\t}\n\t}\n\n\tapiJSON(w, http.StatusOK, pending)\n}\n\nfunc (s *APIServer) handleTimerInfo(w http.ResponseWriter, r *http.Request) {\n\tif r.Method != http.MethodGet {\n\t\thttp.Error(w, \"GET only\", http.StatusMethodNotAllowed)\n\t\treturn\n\t}\n\tif s.timer == nil {\n\t\thttp.Error(w, \"timer scheduler not available\", http.StatusServiceUnavailable)\n\t\treturn\n\t}\n\n\tid := r.URL.Query().Get(\"id\")\n\tif id == \"\" {\n\t\thttp.Error(w, \"id is required\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tjob := s.timer.Store().Get(id)\n\tif job == nil {\n\t\thttp.Error(w, \"timer not found\", http.StatusNotFound)\n\t\treturn\n\t}\n\n\tapiJSON(w, http.StatusOK, job)\n}\n\nfunc (s *APIServer) handleTimerDel(w http.ResponseWriter, r *http.Request) {\n\tif r.Method != http.MethodPost {\n\t\thttp.Error(w, \"POST only\", http.StatusMethodNotAllowed)\n\t\treturn\n\t}\n\tif s.timer == nil {","sourceCodeStart":697,"sourceCodeEnd":733,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/api.go#L697-L733","documentation":"HTTP 400 validation response from the timer-info API endpoint: the `id` query parameter is missing from the GET request, so the timer store cannot be looked up.","triggerScenarios":"Request to the timer-info endpoint without an id query parameter, or with id= empty (e.g. ?id=).","commonSituations":"URL built by string concatenation where the id variable was empty; missing encodeURIComponent on a template; querying info before creating any timer.","solutions":["Append ?id=<timer-job-id> to the request URL","Verify the id variable in the calling code is non-empty before issuing the request","Use the id returned when the timer job was created (e.g. from the timer-add response)"],"exampleFix":"// before\nGET /api/timer/info\n// after\nGET /api/timer/info?id=abc123","handlingStrategy":"validation","validationCode":"if (!id) throw new Error('timer id is required');\nconst res = await fetch(`/api/timer/info?id=${encodeURIComponent(id)}`);","typeGuard":"function hasTimerId(q) { return typeof q?.id === 'string' && q.id.trim().length > 0; }","tryCatchPattern":null,"preventionTips":["Always encodeURIComponent the id in the query string","Keep the id returned at job creation in typed state, not loose strings","Check for empty id after async lookups before calling the API"],"tags":["http-api","validation","query-param"],"backgroundTag":"missing-required-argument","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}