{"record":{"id":"b156610697b3a5ec","repo":"chenhg5/cc-connect","slug":"timer-not-found","errorCode":null,"errorMessage":"timer not found","messagePattern":"timer not found","errorType":"http","errorClass":null,"httpStatus":404,"severity":"error","filePath":"core/api.go","lineNumber":721,"sourceCode":"func (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 {\n\t\thttp.Error(w, \"timer scheduler not available\", http.StatusServiceUnavailable)\n\t\treturn\n\t}\n\n\tvar req struct {\n\t\tID string `json:\"id\"`","sourceCodeStart":703,"sourceCodeEnd":739,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/api.go#L703-L739","documentation":"HTTP 404 response from the timer-info API endpoint: an `id` was supplied but the timer store's Get returned nil, meaning no timer job with that ID exists (already fired, deleted, or never created).","triggerScenarios":"Requesting timer info with an id that was never created, already deleted via timer-del, or from a previous server run whose in-memory timer store was reset.","commonSituations":"Stale ids cached in a client after a server restart (timer store is not durable); double-delete races; typos in the id.","solutions":["List current timer jobs first and confirm the id exists before querying info","Re-create the timer job if the server restarted (in-memory store)","Check for typos or whitespace in the id","Handle 404 in the client by refreshing the job list instead of retrying the same id"],"exampleFix":"// before\nGET /api/timer/info?id=stale-id  // 404\n// after\nGET /api/timer/list  // confirm valid id, then\nGET /api/timer/info?id=<valid-id>","handlingStrategy":"fallback","validationCode":"const list = await (await fetch('/api/timer/list')).json();\nif (!list.some(j => j.id === id)) throw new Error(`timer ${id} does not exist`);","typeGuard":null,"tryCatchPattern":"try { const job = await getTimerInfo(id); } catch (e) { if (e.status === 404) { refreshJobList(); return null; } throw e; }","preventionTips":["Refresh the job list after any delete or server restart before reusing ids","Assume the timer store is in-memory and non-durable across restarts","Never hardcode timer ids"],"tags":["http-api","not-found","timer"],"backgroundTag":"resource-not-found","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}