{"record":{"id":"f7007fdc9e529843","repo":"mastra-ai/mastra","slug":"source-object-must-be-a-single-relatednodeinfo-obj","errorCode":null,"errorMessage":"Source object must be a single RelatedNodeInfo object","messagePattern":"Source object must be a single RelatedNodeInfo object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/rag/src/document/schema/node.ts","lineNumber":33,"sourceCode":"\n  protected constructor(init?: BaseNodeParams<T>) {\n    const { id_, metadata, relationships } = init || {};\n    this.id_ = id_ ?? randomUUID();\n    this.metadata = metadata ?? ({} as T);\n    this.relationships = relationships ?? {};\n  }\n\n  abstract get type(): ObjectType;\n\n  abstract getContent(): string;\n\n  abstract getMetadataStr(): string;\n\n  get sourceNode(): RelatedNodeInfo<T> | undefined {\n    const relationship = this.relationships[NodeRelationship.SOURCE];\n\n    if (Array.isArray(relationship)) {\n      throw new Error('Source object must be a single RelatedNodeInfo object');\n    }\n\n    return relationship;\n  }\n\n  get prevNode(): RelatedNodeInfo<T> | undefined {\n    const relationship = this.relationships[NodeRelationship.PREVIOUS];\n\n    if (Array.isArray(relationship)) {\n      throw new Error('Previous object must be a single RelatedNodeInfo object');\n    }\n\n    return relationship;\n  }\n\n  get nextNode(): RelatedNodeInfo<T> | undefined {\n    const relationship = this.relationships[NodeRelationship.NEXT];\n","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/rag/src/document/schema/node.ts#L15-L51","documentation":"The BaseNode.sourceNode getter reads the SOURCE relationship and expects a single RelatedNodeInfo object. If the stored relationship is an array (the shape used for CHILD-style relationships), it throws because a source is by definition one node.","triggerScenarios":"Reading node.sourceNode when node.relationships[NodeRelationship.SOURCE] was manually assigned an array, e.g. relationships: { [NodeRelationship.SOURCE]: [info] }.","commonSituations":"Hand-building node relationships instead of using node factories, or deserializing/copying relationship maps and wrapping values in arrays uniformly.","solutions":["Assign the SOURCE relationship as a single object: relationships[NodeRelationship.SOURCE] = relatedNodeInfo (not [relatedNodeInfo]).","If data comes from serialized JSON, normalize arrays to a single object before constructing/using the node.","Use library constructors/builders to populate relationships rather than mutating the relationships map directly."],"exampleFix":"// before\nnode.relationships[NodeRelationship.SOURCE] = [sourceInfo];\n// after\nnode.relationships[NodeRelationship.SOURCE] = sourceInfo;","handlingStrategy":"type-guard","validationCode":"const rel = node.relationships[NodeRelationship.SOURCE];\nconst hasValidSource = rel !== undefined && !Array.isArray(rel);","typeGuard":"const isSingleRelatedNodeInfo = <T extends NodeRelationship>(v: unknown): v is RelatedNodeInfo<T> =>\n  v !== null && typeof v === 'object' && !Array.isArray(v) && 'nodeId' in v;","tryCatchPattern":"let source: RelatedNodeInfo | undefined;\ntry {\n  source = node.sourceNode;\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Source object must be')) {\n    const rel = node.relationships[NodeRelationship.SOURCE];\n    source = Array.isArray(rel) ? rel[0] : undefined;\n  } else throw e;\n}","preventionTips":["Only mutate relationships via library helpers, not direct map writes.","Normalize relationship shapes right after deserialization.","Type relationship assignments narrowly so arrays are rejected by the compiler."],"tags":["data-structure","rag","relationships"],"backgroundTag":"invalid-relationship-shape","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}