coleam00/Archon · warning

(err as Error).message

Error message

(err as Error).message

What it means

This is not a thrown error but a captured error message recorded in the cleanup report's `errors` array by cleanupContainerEnvironments. When the reaper fails to remove a stale container isolation environment (the container-runtime removal call or its database row cleanup throws), the per-row failure is caught so one bad environment does not abort the whole reap. The message plus a structured 'container_env_reap_failed' warn log carry the full evidence.

Source

Thrown at packages/core/src/services/cleanup-service.ts:218

      });
      continue;
    }
    if (row.days_since_created < daysStale) {
      report.skipped.push({
        id: row.id,
        reason: `${Math.floor(row.days_since_created)}d old (< ${daysStale}d threshold)`,
      });
      continue;
    }
    try {
      await backend.destroy(row.id);
      report.removed.push(row.id);
      // No runId: the reap only happens when no run can still claim this env.
      getLog().info({ envId: row.id }, 'container_env_reaped');
    } catch (err) {
      report.errors.push({ id: row.id, error: (err as Error).message });
      getLog().warn({ err, envId: row.id }, 'container_env_reap_failed');
    }
  }
  return report;
}

/**
 * Called when a platform conversation is closed (e.g., GitHub issue/PR closed)
 * Cleans up the associated isolation environment unless a workflow run can still
 * claim it. Conversation references are data, not locks (#2868).
 */
export async function onConversationClosed(
  platformType: string,
  platformConversationId: string,
  options?: { merged?: boolean }
): Promise<void> {
  getLog().info({ platformType, platformConversationId }, 'conversation_closed');

  // Find the conversation
  const conversation = await conversationDb.getConversationByPlatformId(

View on GitHub (pinned to 0773b97458)

Solutions

  1. Inspect the structured 'container_env_reap_failed' log entry for the full err object — the captured message is only the summary.
  2. Verify the container runtime (docker/podman) is up and the socket is accessible.
  3. Re-run the reap after the runtime recovers; the row stays and is retried on the next pass.
  4. If the DB row is orphaned (container truly gone), remove the row through the normal env-removal path so DB and runtime re-converge.
Defensive patterns

Strategy: try-catch

Validate before calling

// before triggering reap
const dockerOk = await Bun.spawn(['docker', 'info'], { stdout: 'ignore', stderr: 'ignore' }).exited.then(c => c === 0);
if (!dockerOk) throw new Error('container runtime unavailable; defer reap');

Type guard

function isRecordedReapError(r: unknown): r is { id: string; error: string } {
  return typeof r === 'object' && r !== null
    && typeof (r as { id?: unknown }).id === 'string'
    && typeof (r as { error?: unknown }).error === 'string'
    && (r as { error: string }).error.length > 0;
}

Try / catch

try {
  await reapEnvironment(row);
  report.removed.push(row.id);
} catch (err) {
  getLog().warn({ err, envId: row.id }, 'container_env_reap_failed');
  report.errors.push({ id: row.id, error: (err as Error).message });
  // continue with remaining rows — one failure must not abort the sweep
}

Prevention

When it happens

Trigger: Running the container environment reap (via containerReport or report) over stale rows where the container runtime call fails: container already removed out-of-band but still in the DB, docker/podman daemon unreachable, runtime rejecting removal of a running or locked container, or volume/filesystem cleanup failing.

Common situations: Docker daemon restarted or not running when cleanup fires; a container manually deleted with `docker rm` leaving an orphaned DB row; permission errors on the docker socket in service deployments; container in a state that refuses removal (paused, dead with locked resources).

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/381728ad0a67f639. Report an issue: GitHub.