nanocoai/nanoclaw · error

Container name collision: existing container is not this ses

Error message

Container name collision: existing container is not this session

What it means

Docker driver throws this when a container already exists with the name this session wants, but the existing container's labels (install slug, agent group, session) don't match. It's a guard against one session's container name being taken by another session or another NanoClaw install, so prepare refuses rather than hijacking the container.

Source

Thrown at src/drivers/docker-driver.ts:434

   * container. Adopting one by name would attach this session to a runtime it
   * does not own, so the canonical labels are verified and a mismatch refuses
   * loudly instead of aliasing.
   */
  #existingSession(name: string, key: SessionKey): boolean {
    let out: string;
    try {
      out = this.#cli.run([
        'inspect',
        '--format',
        `{{index .Config.Labels "${LABELS.install}"}}|{{index .Config.Labels "${LABELS.group}"}}|{{index .Config.Labels "${LABELS.session}"}}`,
        name,
      ]);
    } catch {
      return false;
    }
    const [install, group, session] = out.trim().split('|');
    if (install === key.installSlug && group === key.agentGroupId && session === key.sessionId) return true;
    log.warn('Container name collision: existing container is not this session', {
      containerName: name,
      wanted: key,
      found: { install, group, session },
    });
    throw asFailureError({ kind: 'unknown', retryable: false, opaqueRef: `name-collision-${name}` });
  }
}

class DockerHandle implements SessionHandle {
  #proc: SupervisedProcess | null = null;
  /** Log hygiene only — events are never intent-filtered here (that is the hub's job). */
  #stopping = false;
  /** Exit code the attach process observed; undefined until it exits. */
  #attachExitCode: number | null | undefined;
  readonly #stderrTail: string[] = [];

  constructor(
    readonly key: SessionKey,

View on GitHub (pinned to 294ef2aee8)

Solutions

  1. Run docker ps -a | grep <containerName> and inspect its labels to identify which install/session owns it
  2. If it's a stale/orphaned container from this install, docker rm -f it and retry prepare
  3. If it belongs to another install, change the install slug / container naming so the two installs don't collide
  4. Never force-reuse the name; the mismatch means session data would cross installs

Example fix

# before
collision on nanoclaw-abc123 — unclear owner

# after
docker inspect nanoclaw-abc123 --format '{{.Config.Labels}}'
docker rm -f nanoclaw-abc123   # if stale from this install
# then retry session start
Defensive patterns

Strategy: try-catch

Validate before calling

import { isFailureError } from 'src/failures.js';
// before prepare(), check ownership:
// docker inspect <name> labels match installSlug/agentGroupId/sessionId

Type guard

function isNameCollisionFailure(e: unknown): boolean {
  return typeof (e as any)?.opaqueRef === 'string' &&
    (e as any).opaqueRef.startsWith('name-collision-');
}

Try / catch

try {
  await driver.prepare(session);
} catch (e) {
  if (isNameCollisionFailure(e)) {
    // inspect & remove the foreign/stale container, then surface to operator
  } else throw e;
}

Prevention

When it happens

Trigger: prepare() for session X finds container nanoclaw-<hash> exists; docker inspect label query returns a different installSlug/agentGroupId/sessionId triple; a non-retryable name-collision failure is thrown.

Common situations: Two NanoClaw installs on one host generating colliding names; stale container left after an unclean shutdown with a re-derived session key; manual container created with a conflicting name; changed install slug without cleaning old containers.

Related errors


AI-assisted analysis of nanocoai/nanoclaw@294ef2aee8 (2026-08-28). Data as JSON: /api/errors/8ffaaf5b41bcf2f9. Report an issue: GitHub.