ruvnet/RuView · error · Error
brain line ${index + 1}: ${errors.join('; ')}
Error message
brain line ${index + 1}: ${errors.join('; ')} What it means
Each parsed line must pass validateBrainRecord with canonical:true: non-empty string id/title/content/evidence; id matching /^[a-z0-9][a-z0-9-]{2,63}$/; evidence in {REPOSITORY, POLICY, ADR, MEASURED, SYNTHETIC}; a repository-relative source.path with positive integer source.line; string tags; content <= 8192 chars; title <= 200 chars; reviewed === true; and title+content not matching the SECRET or INJECTION regexes. All violations are joined with '; ' into this message.
Source
Thrown at harness/ruview/src/brain.js:51
if (!Array.isArray(record.tags) || record.tags.some((tag) => typeof tag !== 'string')) errors.push('tags must be strings');
if ((record.content || '').length > 8192) errors.push('content exceeds 8192 characters');
if ((record.title || '').length > 200) errors.push('title exceeds 200 characters');
if (canonical && record.reviewed !== true) errors.push('canonical records must be reviewed');
const combined = `${record.title || ''}\n${record.content || ''}`;
if (SECRET.test(combined)) errors.push('record appears to contain a secret');
if (INJECTION.test(combined)) errors.push('record contains instruction-like prompt injection');
return errors;
}
export function loadBrain(path = CORPUS_PATH) {
const raw = readFileSync(path, 'utf8').replace(/\r\n/g, '\n');
if (Buffer.byteLength(raw) > 1_048_576) throw new Error('brain corpus exceeds 1 MiB');
const records = raw.split('\n').filter(Boolean).map((line, index) => {
if (Buffer.byteLength(line) > 16_384) throw new Error(`brain line ${index + 1}: exceeds 16 KiB`);
let record;
try { record = JSON.parse(line); } catch (error) { throw new Error(`brain line ${index + 1}: ${error.message}`); }
const errors = validateBrainRecord(record, { canonical: true });
if (errors.length) throw new Error(`brain line ${index + 1}: ${errors.join('; ')}`);
return Object.freeze(record);
});
if (records.length > 1000) throw new Error('brain corpus exceeds 1000 records');
const ids = new Set();
for (const record of records) {
if (ids.has(record.id)) throw new Error(`duplicate brain id: ${record.id}`);
ids.add(record.id);
}
return { records, digest: sha256(raw), bytes: Buffer.byteLength(raw) };
}
function terms(value) {
return new Set(String(value).toLowerCase().match(/[a-z0-9][a-z0-9_-]{1,}/g) || []);
}
export function searchBrain(query, { limit = 8, path = CORPUS_PATH } = {}) {
const wanted = terms(query);
if (!wanted.size) return [];View on GitHub (pinned to 4685618388)
Solutions
- Fix every field named in the message; the joined list reports all violations for that line at once
- Use 'brain propose' to emit unreviewed records for a PR instead of hand-writing canonical entries
- Model new records on existing valid lines in core.jsonl
Example fix
// before
{"id":"New_Lesson","title":"T","content":"C","evidence":"docs","source":{"path":"/abs/x.js","line":0},"tags":["a"]}
// after
{"id":"new-lesson","title":"T","content":"C","evidence":"REPOSITORY","source":{"path":"src/x.js","line":1},"tags":["a"],"reviewed":true} Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from 'node:fs';
import { validateBrainRecord } from './harness/ruview/src/brain.js';
function invalidRecords(path) {
return readFileSync(path, 'utf8').split('\n')
.filter((l) => l.trim())
.map((line, i) => [i + 1, validateBrainRecord(JSON.parse(line), { canonical: true })])
.filter(([, errors]) => errors.length > 0);
} Try / catch
try {
const brain = loadBrain(path);
} catch (error) {
if (error.message.includes('must be') || error.message.includes('canonical records')) {
console.error(`record validation failed: ${error.message}`);
process.exit(1);
}
throw error;
} Prevention
- Reuse the exported validateBrainRecord() as a pre-commit lint over proposed records
- Canonical corpus entries require reviewed:true — route additions through 'brain propose' and review
- Check the closed enums: evidence must be REPOSITORY, POLICY, ADR, MEASURED, or SYNTHETIC, and source.path must be repository-relative
When it happens
Trigger: Adding a canonical record without "reviewed": true, using evidence: "docs" instead of an allowed enum, an absolute or ..-traversing source.path, an id like 'My_Record' or shorter than 3 chars, or content containing 'api_key: ...' or 'ignore previous' style phrases.
Common situations: Contributors editing brain/corpus/core.jsonl directly instead of using the review flow, records copied from notes without citations, example tokens in content tripping the secret scanner.
Related errors
- brain line ${index + 1}: exceeds 16 KiB
- brain line ${index + 1}: ${error.message}
- duplicate brain id: ${record.id}
- brain corpus exceeds 1 MiB
- brain corpus exceeds 1000 records
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/c67300ee7b4dc363.
Report an issue: GitHub.