different-ai/openwork · info · Error

ABORT_ERR

ABORT_ERR

Error message

File read aborted

What it means

throwIfAborted in jsonc.ts converts an already-aborted AbortSignal into a thrown error: if the signal's reason is an Error it is rethrown as-is, otherwise a generic Error with code ABORT_ERR and message "File read aborted" is thrown. Bounded file reads call it at every checkpoint so a cancelled read stops promptly.

Source

Thrown at apps/server/src/jsonc.ts:41

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}

function hasErrorCode(error: unknown, code: string): boolean {
  return isRecord(error) && error.code === code;
}

function fileReadError(code: string, message: string): Error {
  const error = new Error(message);
  Object.defineProperty(error, "code", { value: code, enumerable: true });
  return error;
}

function throwIfAborted(signal: AbortSignal | undefined): void {
  if (!signal?.aborted) return;
  if (signal.reason instanceof Error) throw signal.reason;
  throw fileReadError("ABORT_ERR", "File read aborted");
}

/**
 * Read a small diagnostics input without following symlinks or opening a FIFO
 * in blocking mode. The size is checked both before and while reading so a
 * file that grows after inspection cannot exceed the caller's memory budget.
 */
export async function readBoundedRegularTextFile(
  path: string,
  options: { maxBytes: number; signal?: AbortSignal },
): Promise<string> {
  if (!Number.isSafeInteger(options.maxBytes) || options.maxBytes < 0) {
    throw new RangeError("maxBytes must be a non-negative safe integer");
  }
  throwIfAborted(options.signal);
  const pathMetadata = await lstat(path);
  throwIfAborted(options.signal);
  if (!pathMetadata.isFile()) {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Check signal.aborted before initiating the read and skip the call if already cancelled.
  2. Size the AbortController timeout generously enough for the read to finish.
  3. Catch ABORT_ERR (or the signal's own reason) and treat it as normal cancellation, not a file failure.
  4. Reuse a single controller per logical operation so aborts are intentional and observable.

Example fix

// before
const text = await readJsoncFile(path, { signal: controller.signal }); // throws ABORT_ERR when cancelled
// after
if (controller.signal.aborted) return null;
try {
  return await readJsoncFile(path, { signal: controller.signal });
} catch (e) {
  if ((e as NodeJS.ErrnoException).code === "ABORT_ERR") return null;
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (signal?.aborted) return null; // skip the read entirely

Type guard

null

Try / catch

try {
  return await readJsoncFile(path, { signal });
} catch (e) {
  if ((e as NodeJS.ErrnoException).code === "ABORT_ERR" || (e as Error)?.name === "AbortError") return null;
  throw e;
}

Prevention

When it happens

Trigger: Passing an AbortSignal to readBoundedRegularTextFile/readJsoncFile that is already aborted, or aborting it mid-read (request timeout, caller cancellation) at one of the throwIfAborted checkpoints before, between, or during chunk reads.

Common situations: HTTP handlers whose request is cancelled while reading a diagnostics JSONC file; AbortSignal.timeout firing during a slow disk read; callers cancelling scans before the file read completes.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/160a54f13caa6225. Report an issue: GitHub.