{"record":{"id":"0a24f9d5ae62d137","repo":"gastownhall/beads","slug":"timeout-waiting-for-proxy-on-s","errorCode":null,"errorMessage":"timeout waiting for proxy on %s","messagePattern":"timeout waiting for proxy on (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/endpoint.go","lineNumber":288,"sourceCode":"\t\tcase !lockfile.IsLocked(err):\n\t\t\treturn Endpoint{}, fmt.Errorf(\"probe proxy lock: %w\", err)\n\t\tcase discovery.status == adoptionLegacy:\n\t\t\trecordPath := pidfile.Path(rootDir, PIDFileName)\n\t\t\treturn Endpoint{}, fmt.Errorf(\n\t\t\t\t\"legacy proxy record %s is protected by held lock %s; stop the pre-upgrade proxy with the old bd binary or wait for its idle exit, then quarantine the record manually by renaming %s to %s.stale-<unix-timestamp> before retrying\",\n\t\t\t\trecordPath,\n\t\t\t\tfilepath.Join(rootDir, LockFileName),\n\t\t\t\trecordPath,\n\t\t\t\trecordPath,\n\t\t\t)\n\t\t}\n\n\t\tselect {\n\t\tcase <-timeout.C:\n\t\t\tif lastSpawnErr != nil {\n\t\t\t\treturn Endpoint{}, lastSpawnErr\n\t\t\t}\n\t\t\treturn Endpoint{}, fmt.Errorf(\"timeout waiting for proxy on %s\", rootDir)\n\t\tcase <-poll.C:\n\t\t}\n\t}\n}\n\nfunc adoptedEndpoint(rootDir, want string, discovery adoptionResult) (Endpoint, error) {\n\tif want != \"\" && discovery.pidfile.UpstreamID != \"\" && discovery.pidfile.UpstreamID != want {\n\t\treturn Endpoint{}, &ErrUpstreamMismatch{\n\t\t\tRootDir: rootDir,\n\t\t\tWant:    want,\n\t\t\tHave:    discovery.pidfile.UpstreamID,\n\t\t}\n\t}\n\treturn discovery.endpoint, nil\n}\n\nfunc spawnAndHandoff(\n\trootDir string,","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/endpoint.go#L270-L306","documentation":"The caller gave up: for the full openDeadline window, GetCreateDatabaseProxyServerEndpoint polled for a usable proxy endpoint and none materialized, and no concrete spawn error was recorded (lastSpawnErr was nil). This is the generic 'proxy never appeared' timeout — usually the spawn marker indicates activity that never completes, or repeated lock races kept deferring the spawn until the deadline.","triggerScenarios":"The discovery loop cycles (record absent/incomplete, spawn marker seen as active, TryLock fails as held) continuously until timeout.C fires with lastSpawnErr == nil. E.g. a previous opener crashed after creating a spawn marker without clearing it, or processes fight over proxy.lock forever.","commonSituations":"Stale spawn marker left by a killed/crashed opener process (SIGKILL mid-spawn); another very long-running opener legitimately holding the lock for longer than openDeadline; extremely slow disk causing repeated IOErr-free but incomplete reads; watchdog restarting bd in a tight loop, each invocation restarting the wait.","solutions":["Check whether a bd proxy process is actually running (pgrep -af bd); if a spawn is genuinely in progress, just wait or increase the deadline","If no process is running, remove the stale spawn marker and proxy record in <rootDir> and retry","Look for competing openers (CI jobs, other terminals) repeatedly locking proxy.lock and serialize them","Capture a verbose log of the loop; if lastSpawnErr was swallowed, address the underlying spawn failure instead"],"exampleFix":"// before\nerror: timeout waiting for proxy on /repo/.beads\n// after\n$ pgrep -af bd || echo none\n$ rm -f /repo/.beads/proxy.spawn-marker /repo/.beads/proxy.pid  # only if no bd process is alive\n$ bd ready","handlingStrategy":"retry","validationCode":"// Confirm no zombie spawn artifacts before waiting the full deadline\nmarker := filepath.Join(rootDir, \"proxy.spawn-marker\")\nif fi, err := os.Stat(marker); err == nil && time.Since(fi.ModTime()) > 5*time.Minute {\n    os.Remove(marker) // stale marker from a crashed opener\n}","typeGuard":null,"tryCatchPattern":"ep, err := proxy.GetCreateDatabaseProxyServerEndpoint(root, opts)\nif err != nil && strings.Contains(err.Error(), \"timeout waiting for proxy\") {\n    // one clean retry after clearing stale artifacts\n    os.Remove(filepath.Join(rootDir, \"proxy.spawn-marker\"))\n    ep, err = proxy.GetCreateDatabaseProxyServerEndpoint(root, opts)\n}","preventionTips":["Clean spawn artifacts after SIGKILL'd processes","Avoid many concurrent openers on the same workspace","Alert on open latency approaching the deadline"],"tags":["timeout","proxy","concurrency","polling"],"backgroundTag":"proxy-startup-timeout","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}