paperclipai/paperclip · error · Error
Source content is ${sourceBytes} bytes, which exceeds the co
Error message
Source content is ${sourceBytes} bytes, which exceeds the configured LLM Wiki source limit of ${maxSourceBytes} bytes. What it means
Thrown by assertSourceWithinConfiguredLimit() when the byte length of source content about to be ingested exceeds the configured maxSourceBytes (default DEFAULT_MAX_SOURCE_BYTES = 250000, overridable via config.maxSourceBytes). The actual byte count and the limit are both interpolated. The check uses byteLength() (raw bytes, not characters), so multi-byte content is measured correctly.
Source
Thrown at packages/plugins/plugin-llm-wiki/src/wiki/core.ts:694
]);
return {
...base,
maxCharacters: Math.min(base.maxCharacters, profile.cursor.maxWindowCharacters),
maxCharactersPerSource: Math.min(base.maxCharactersPerSource, profile.cursor.maxCharactersPerSource),
};
}
function estimateSourceCostCents(characters: number, costCentsPerThousandSourceCharacters: number): number {
if (characters <= 0 || costCentsPerThousandSourceCharacters <= 0) return 0;
return Math.ceil((characters / 1000) * costCentsPerThousandSourceCharacters);
}
async function assertSourceWithinConfiguredLimit(ctx: PluginContext, companyId: string, contents: string) {
const config = await ctx.config.get(companyId);
const maxSourceBytes = normalizeMaxSourceBytes(config.maxSourceBytes);
const sourceBytes = byteLength(contents);
if (sourceBytes > maxSourceBytes) {
throw new Error(`Source content is ${sourceBytes} bytes, which exceeds the configured LLM Wiki source limit of ${maxSourceBytes} bytes.`);
}
}
function normalizeEventIngestionSettings(value: unknown): WikiEventIngestionSettings {
if (!value || typeof value !== "object" || Array.isArray(value)) {
return { ...DEFAULT_EVENT_INGESTION_SETTINGS, sources: { ...DEFAULT_EVENT_INGESTION_SETTINGS.sources } };
}
const record = value as Record<string, unknown>;
const sources = record.sources && typeof record.sources === "object" && !Array.isArray(record.sources)
? record.sources as Record<string, unknown>
: {};
const maxCharacters = typeof record.maxCharacters === "number" && Number.isFinite(record.maxCharacters)
? Math.max(1000, Math.min(MAX_EVENT_SOURCE_CHARS, Math.floor(record.maxCharacters)))
: DEFAULT_EVENT_INGESTION_SETTINGS.maxCharacters;
return {
enabled: normalizeBoolean(record.enabled, DEFAULT_EVENT_INGESTION_SETTINGS.enabled),
sources: {
issues: normalizeBoolean(sources.issues, DEFAULT_EVENT_INGESTION_SETTINGS.sources.issues),View on GitHub (pinned to 67001ec6eb)
Solutions
- Reduce the content size below maxSourceBytes (split into multiple ingestions, truncate, or summarize).
- Raise config.maxSourceBytes for the company (be aware of ingestion cost and LLM context downstream).
- Pre-check byteLength(content) before calling the ingest path and chunk if it exceeds the limit.
Example fix
// before
await assertSourceWithinConfiguredLimit(ctx, companyId, hugeContent); // throws if > 250000 bytes
// after
const MAX = 250_000;
if (Buffer.byteLength(hugeContent) > MAX) {
// chunk or truncate hugeContent
}
await assertSourceWithinConfiguredLimit(ctx, companyId, truncatedContent); Defensive patterns
Strategy: validation
Validate before calling
function byteLength(s: string): number {
return typeof Buffer !== "undefined" ? Buffer.byteLength(s) : new TextEncoder().encode(s).length;
}
async function getMax(ctx: PluginContext, companyId: string): Promise<number> {
const cfg = await ctx.config.get(companyId);
const max = cfg?.maxSourceBytes;
return typeof max === "number" && Number.isFinite(max) ? max : 250_000;
}
const max = await getMax(ctx, companyId);
if (byteLength(content) > max) { /* chunk or truncate */ } Try / catch
try {
await assertSourceWithinConfiguredLimit(ctx, companyId, content);
} catch (err) {
if (err instanceof Error && err.message.includes("exceeds the configured LLM Wiki source limit")) {
// split content, then ingest each chunk separately
} else throw err;
} Prevention
- Pre-measure byte length (not char length) of source content.
- Chunk large inputs before ingestion.
- Tune config.maxSourceBytes to the workload if justified by downstream LLM context.
When it happens
Trigger: Ingesting a large source document, log dump, or concatenated event payload whose UTF-8 byte size exceeds maxSourceBytes. Default 250000 bytes (~250KB) exceeded by a single big file or by aggregating many events.
Common situations: Ingesting a repo README plus attached logs. Bulk event ingestion that concatenates many records into one source. maxSourceBytes not tuned for the workload. Unicode-heavy content where character count under-represents byte count.
Related errors
- ${decision.message}
- Ingest operation did not return an issue id; the dropped fil
- Paperclip source scope must specify either projectId or root
- ${name} must be a positive number.
- ${name} exceeds the hard Paperclip ingestion cap of ${max} c
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/e786fca05a13d295.
Report an issue: GitHub.