{"record":{"id":"c6c4226833b36bb8","repo":"nanocoai/nanoclaw","slug":"failed-to-clean-up-orphaned-containers","errorCode":null,"errorMessage":"Failed to clean up orphaned containers","messagePattern":"Failed to clean up orphaned containers","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/drivers/docker-driver.ts","lineNumber":349,"sourceCode":"        'status=exited',\n        '--filter',\n        'status=created',\n        '--filter',\n        'status=dead',\n        '--format',\n        '{{.Names}}',\n      ]);\n      const stale = out.trim().split('\\n').filter(Boolean);\n      for (const name of stale) {\n        try {\n          this.#cli.run(['rm', '--force', validateRuntimeName(name, 'container')]);\n        } catch {\n          /* already gone */\n        }\n      }\n      if (stale.length > 0) log.info('Removed orphaned containers', { count: stale.length, names: stale });\n    } catch (err) {\n      log.warn('Failed to clean up orphaned containers', { err });\n    }\n\n    // Pre-seam residue: containers spawned before the driver seam carry the\n    // install label but not the session label, so `listSessions` cannot see\n    // them — they can be neither adopted nor matched to a session. Left alone\n    // they would run forever AND race a freshly-named replacement for the same\n    // session directory. Stopping them is exactly what the old\n    // `cleanupOrphans()` did to every container on every start.\n    try {\n      const out = this.#cli.run([\n        'ps',\n        '--filter',\n        `label=${LABELS.install}=${installSlug}`,\n        '--format',\n        `{{.Names}}|{{.Label \"${LABELS.session}\"}}`,\n      ]);\n      const preSeam = out\n        .trim()","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/drivers/docker-driver.ts#L331-L367","documentation":"During startup residue reaping, the host failed while removing orphaned Docker containers (labeled for this install but not matching any session). Those orphans keep running until the next successful sweep.","triggerScenarios":"The docker rm / list calls inside the orphan-cleanup block throw — daemon hiccup, container already being removed by another process, or name validation rejecting a weird container name.","commonSituations":"Two nanoclaw instances started concurrently, Docker restart mid-sweep, or leftover containers with unusual names from old installs.","solutions":["Run `docker ps -a --filter label=<install-label>` and inspect leftovers","Remove stragglers manually: `docker rm -f <name>`","Restart nanoclaw so the next sweep retries","Ensure only one host instance runs"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const orphans = execSync(\"docker ps -aq --filter label=<install-label>\").toString().trim();","typeGuard":null,"tryCatchPattern":"try { await reap(); } catch { /* next sweep retries; manual docker rm as fallback */ }","preventionTips":["Run only one host instance per install","Restart nanoclaw after Docker outages to re-run the sweep"],"tags":["docker","orphan-cleanup","startup"],"backgroundTag":"docker-cleanup-failed","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}