nexu-io/open-design · error

project_files.read_json file exceeds 256KB

Error message

project_files.read_json file exceeds 256KB

What it means

executeProjectFilesReadJson (refresh.ts:598-599) rejects files whose stat size exceeds 256 * 1024 bytes (256 KiB). This cap keeps the parsed JSON within bounded-JSON limits and avoids loading oversized files into the refresh pipeline.

Source

Thrown at apps/daemon/src/live-artifacts/refresh.ts:599

  }

  return asBoundedRefreshOutput({ toolName: 'project_files.search', query: query ?? '', count: matches.length, truncated: allFiles.length > matches.length && matches.length >= maxResults, matches });
}

async function executeProjectFilesReadJson(options: ExecuteLocalDaemonRefreshSourceOptions): Promise<BoundedJsonObject> {
  const filePath = selectJsonPath(options.source.input as ProjectFilesReadJsonInput);
  if (!filePath.endsWith('.json')) throw new Error('project_files.read_json only supports .json files');
  const dir = projectDir(options.projectsRoot, options.projectId);
  const target = path.resolve(dir, filePath);
  const [dirReal, targetLinkStat] = await Promise.all([realpath(dir), lstat(target)]);
  if (targetLinkStat.isSymbolicLink()) throw new Error('project_files.read_json does not follow symlinks');
  const targetReal = await realpath(target);
  if (!targetReal.startsWith(`${dirReal}${path.sep}`) && targetReal !== dirReal) {
    throw new Error('project_files.read_json path escapes project dir');
  }
  const entryStat = await stat(targetReal);
  if (!entryStat.isFile()) throw new Error('project_files.read_json path must be a file');
  if (entryStat.size > 256 * 1024) throw new Error('project_files.read_json file exceeds 256KB');
  if (options.signal?.aborted === true) throw options.signal.reason;
  let parsed: BoundedJsonValue;
  try {
    parsed = JSON.parse(await readFile(targetReal, 'utf8')) as BoundedJsonValue;
  } catch {
    throw new Error(`project_files.read_json could not parse JSON at ${filePath}`);
  }
  return asBoundedRefreshOutput({ toolName: 'project_files.read_json', path: filePath, size: entryStat.size, json: parsed });
}

function compactExecOutput(value: string): string[] {
  return value.split('\n').map((line) => line.trimEnd()).filter(Boolean).slice(0, 100);
}

async function runGit(projectPath: string, args: string[], signal: AbortSignal | undefined): Promise<string> {
  try {
    const result = await execFileAsync('git', args, { cwd: projectPath, signal, timeout: 10_000, maxBuffer: 128 * 1024 });
    return result.stdout.toString();

View on GitHub (pinned to 5be4028344)

Solutions

  1. Slim the JSON file below 256 KiB by removing unused keys or splitting it.
  2. Point read_json at a smaller, pre-summarized slice of the data.
  3. Use outputMapping.dataPaths so only needed fields are retained (note: the file itself must still be under 256 KiB to be read at all).

Example fix

// before: metrics.json is 1.2 MB
const input = { path: 'metrics.json' };
// throws `project_files.read_json file exceeds 256KB`

// after: extract the needed subset into a smaller file
const input = { path: 'metrics-summary.json' }; // < 256 KiB
Defensive patterns

Strategy: validation

Validate before calling

import { stat } from 'node:fs/promises';
const MAX = 256 * 1024;
async function assertUnderSizeLimit(target: string): Promise<void> {
  const st = await stat(target);
  if (st.size > MAX) throw new Error('project_files.read_json file exceeds 256KB');
}

Prevention

When it happens

Trigger: input.path points to a .json file larger than 256 KiB (262144 bytes).

Common situations: Large data exports, bundled manifests, lockfile-sized JSON, or untrimmed datasets committed to the project.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/75c1ae63d03a5b3b. Report an issue: GitHub.