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
- Check signal.aborted before initiating the read and skip the call if already cancelled.
- Size the AbortController timeout generously enough for the read to finish.
- Catch ABORT_ERR (or the signal's own reason) and treat it as normal cancellation, not a file failure.
- 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
- Check signal.aborted before each expensive call.
- Size AbortSignal.timeout budgets above worst-case disk latency.
- Distinguish cancellation from file errors in catch blocks.
- Reuse one AbortController per logical operation.
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
- ${result}
- Request timed out.
- Failed to write .opencode/openwork.json
- Environment variable store could not be read
- Environment variable store is invalid JSON
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/160a54f13caa6225.
Report an issue: GitHub.