coleam00/Archon · critical

Detached run control directory must have mode 0700: ${direct

Error message

Detached run control directory must have mode 0700: ${directory}

What it means

controlDirectory() enforces that the detached-run control directory has mode exactly 0700 on POSIX ((stat.mode & 0o077) must be 0). A looser mode would let other local users read or interfere with run-control files, so the runtime refuses to proceed. mkdirSync uses mode 0700, so this error means the directory pre-existed with permissive bits or its mode was changed afterwards.

Source

Thrown at packages/cli/src/utils/detached-run-control.ts:68

}

function controlDirectory(): string {
  const uid = process.getuid?.();
  const directory =
    process.platform === 'win32'
      ? join(tmpdir(), 'archon-run-control')
      : `/tmp/archon-${uid === undefined ? 'user' : String(uid)}`;
  mkdirSync(directory, { recursive: true, mode: 0o700 });
  if (process.platform !== 'win32') {
    const stat = lstatSync(directory);
    if (!stat.isDirectory() || stat.isSymbolicLink()) {
      throw new Error(`Detached run control path is not a directory: ${directory}`);
    }
    if (uid !== undefined && stat.uid !== uid) {
      throw new Error(`Detached run control directory is owned by another user: ${directory}`);
    }
    if ((stat.mode & 0o077) !== 0) {
      throw new Error(`Detached run control directory must have mode 0700: ${directory}`);
    }
  }
  return directory;
}

/** Prove the marked POSIX owner has the process group that active cancellation will signal. */
export function assertDetachedRunProcessOwner(): void {
  if (process.platform !== 'win32' && !processGroupExists(process.pid)) {
    throw new Error(
      `Refusing detached run control because process ${String(process.pid)} does not own process group ${String(process.pid)}`
    );
  }
}

/** A bounded, user-scoped endpoint: Unix socket on POSIX, named pipe on Windows. */
export function detachedRunControlPath(runId: string): string {
  const token = endpointToken(runId);
  if (process.platform === 'win32') return `\\\\.\\pipe\\archon-workflow-${token}`;

View on GitHub (pinned to 0773b97458)

Solutions

  1. Tighten the mode: chmod 700 /tmp/archon-<uid>.
  2. If unsure of its provenance and no run is active, remove it (rm -rf) and let Archon recreate it with 0700.
  3. Check your umask / provisioning scripts so the directory is not recreated group/world-readable.

Example fix

// before
$ ls -ld /tmp/archon-1000
drwxr-xr-x
// after
$ chmod 700 /tmp/archon-1000
Defensive patterns

Strategy: validation

Validate before calling

import { lstatSync } from 'node:fs';
function modeIsPrivate(dir: string): boolean {
  try { return (lstatSync(dir).mode & 0o077) === 0; }
  catch { return true; }
}
if (!modeIsPrivate('/tmp/archon-' + (process.getuid() ?? 'user'))) {
  require('node:fs').chmodSync(dir, 0o700);
}

Try / catch

try {
  const dir = controlDirectory();
} catch (err) {
  if (err instanceof Error && err.message.includes('must have mode 0700')) {
    chmodSync(expectedControlDir, 0o700); // then retry
  } else throw err;
}

Prevention

When it happens

Trigger: lstatSync shows group/other permission bits set on the control directory (e.g. 0755) when resolving a detached-run control path or lock path on POSIX.

Common situations: Directory created earlier by an older version or different tool with a umask that yielded 0755; admin manually chmod'd the tmp dir; some provisioning step set a permissive umask before creation.

Related errors


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