affaan-m/ECC · error · Error

Failed to write ${path.basename(filePath)}: ${error.message}

Error message

Failed to write ${path.basename(filePath)}: ${error.message}

What it means

_fetch_import_url() reads at most max_bytes+1 bytes from the response and rejects if the body exceeds the limit (default 2 MiB = 2*1024*1024). This bounds the instinct file size to prevent memory exhaustion and oversized-payload denial of service. The over-read-by-one technique lets the validator detect the overflow without buffering the entire response.

Source

Thrown at scripts/ci/catalog.js:76

    agents: { count: agents.length, files: agents, glob: 'agents/*.md' },
    commands: { count: commands.length, files: commands, glob: 'commands/*.md' },
    skills: { count: skills.length, files: skills, glob: 'skills/*/SKILL.md' }
  };
}

function readFileOrThrow(filePath) {
  try {
    return fs.readFileSync(filePath, 'utf8');
  } catch (error) {
    throw new Error(`Failed to read ${path.basename(filePath)}: ${error.message}`);
  }
}

function writeFileOrThrow(filePath, content) {
  try {
    fs.writeFileSync(filePath, content, 'utf8');
  } catch (error) {
    throw new Error(`Failed to write ${path.basename(filePath)}: ${error.message}`);
  }
}

function replaceOrThrow(content, regex, replacer, source) {
  if (!regex.test(content)) {
    throw new Error(`${source} is missing the expected catalog marker`);
  }

  return content.replace(regex, replacer);
}

function parseReadmeExpectations(readmeContent) {
  const expectations = [];

  const quickStartMatch = readmeContent.match(
    /access to\s+(\d+)\s+agents,\s+(\d+)\s+skills,\s+and\s+(\d+)\s+(?:commands|legacy command shims?)/i
  );
  if (!quickStartMatch) {

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Trim the instinct file below 2 MiB and re-host it.
  2. Split a large instinct set into multiple smaller files and import them separately.
  3. If you call _fetch_import_url directly (not via the CLI), pass a larger max_bytes only if you trust the source and have memory headroom.

Example fix

# before
content = _fetch_import_url(url)  # >2MiB file rejected

# after (direct call with raised limit for a trusted source)
content = _fetch_import_url(url, max_bytes=8 * 1024 * 1024)
Defensive patterns

Strategy: validation

Validate before calling

# HEAD the URL to check Content-Length before fetching the body.
import urllib.request
req = urllib.request.Request(url, method='HEAD')
with urllib.request.urlopen(req, timeout=15) as resp:
    length = int(resp.headers.get('Content-Length', 0))
if length > 2 * 1024 * 1024:
    raise SystemExit(f'file is {length} bytes — exceeds the 2 MiB import limit')

Type guard

MAX_BYTES = 2 * 1024 * 1024

def within_size(num_bytes: int) -> bool:
    return num_bytes <= MAX_BYTES

Try / catch

try:
    content = _fetch_import_url(source)
except ValueError as e:
    if 'exceeds' in str(e):
        log.error('instinct file too large — trim it below 2 MiB or split into multiple files')
    raise

Prevention

When it happens

Trigger: Importing an instinct file larger than 2 MiB; the URL accidentally points at a large markdown archive or dataset; a server returns an unexpectedly huge response.

Common situations: A bundled instinct pack grew past the limit; the URL was mistyped and points to a large unrelated file; a generated instinct dump exceeds the threshold.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/eb1c80e5f5ba1d0d. Report an issue: GitHub.