{"record":{"id":"ea906a03753b6128","repo":"ruvnet/RuView","slug":"duplicate-brain-id-record-id","errorCode":null,"errorMessage":"duplicate brain id: ${record.id}","messagePattern":"duplicate brain id: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"harness/homecore/src/brain.js","lineNumber":91,"sourceCode":"  if (Buffer.byteLength(raw) > 1_048_576) throw new Error('brain corpus exceeds 1 MiB');\n  const records = raw.split('\\n').filter(Boolean).map((line, index) => {\n    if (Buffer.byteLength(line) > 16_384) {\n      throw new Error(`brain line ${index + 1}: exceeds 16 KiB`);\n    }\n    let record;\n    try {\n      record = JSON.parse(line);\n    } catch (error) {\n      throw new Error(`brain line ${index + 1}: ${error.message}`);\n    }\n    const errors = validateBrainRecord(record, { canonical: true });\n    if (errors.length) throw new Error(`brain line ${index + 1}: ${errors.join('; ')}`);\n    return Object.freeze(record);\n  });\n  if (records.length > 1000) throw new Error('brain corpus exceeds 1000 records');\n  const ids = new Set();\n  for (const record of records) {\n    if (ids.has(record.id)) throw new Error(`duplicate brain id: ${record.id}`);\n    ids.add(record.id);\n  }\n  return { records, digest: sha256(raw), bytes: Buffer.byteLength(raw) };\n}\n\nfunction terms(value) {\n  return new Set(String(value).toLowerCase().match(/[a-z0-9][a-z0-9_-]{1,}/g) || []);\n}\n\nexport function searchBrain(query, { limit = 8, path = CORPUS_PATH } = {}) {\n  const wanted = terms(query);\n  if (!wanted.size) return [];\n  const { records, digest } = loadBrain(path);\n  return records.map((record) => {\n    const title = terms(record.title);\n    const body = terms(record.content);\n    const tags = new Set(record.tags.map((tag) => tag.toLowerCase()));\n    let score = 0;","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/harness/homecore/src/brain.js#L73-L109","documentation":"Raised at auth.py:265 after a token passes signature and expiry verification but its decoded payload has no 'sub' claim (or sub is empty/None). The middleware requires sub to carry the username it will look up in UserManager.","triggerScenarios":"Calling TokenManager.create_access_token({'email': ...}) without a 'sub' key; tokens minted by a different service that uses 'username' or 'user_id' as the subject claim instead of 'sub'; payload.get('sub') returning '' because an empty string was set.","commonSituations":"Custom token issuance code that forgets the sub claim; integrating third-party-issued JWTs whose claim names differ; test fixtures hand-crafting payloads with only exp/iat.","solutions":["Always include 'sub': username when building token_data before create_access_token","If consuming foreign tokens, map their subject claim to sub before verification or extend the lookup to the actual claim name","Validate issued tokens with jwt.io / decode_token_claims to confirm sub is present"],"exampleFix":"# before\naccess_token = token_manager.create_access_token({\"email\": email})\n# after\naccess_token = token_manager.create_access_token({\"sub\": username, \"email\": email})","handlingStrategy":"validation","validationCode":"def token_data_is_valid(token_data: dict) -> bool:\n    \"\"\"create_access_token payload must carry a non-empty sub for _authenticate_request.\"\"\"\n    return bool(token_data.get(\"sub\"))","typeGuard":"def has_subject_claim(claims: dict) -> bool:\n    return isinstance(claims.get(\"sub\"), str) and len(claims[\"sub\"]) > 0","tryCatchPattern":"try:\n    user_info = await middleware._authenticate_request(request)\nexcept AuthenticationError as e:\n    if str(e) == \"Invalid token payload\":\n        # token verified but lacks sub -> re-issue with sub at the token mint\n        return json_response({\"error\": \"token missing sub claim; re-issue required\"}, 401)\n    raise","preventionTips":["Always set sub when minting tokens","Decode new tokens with decode_token_claims in tests and assert sub exists","Document 'sub = username' as the token contract"],"tags":["auth","jwt","claims"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}