{"record":{"id":"e65e3954f53bbc10","repo":"BigPizzaV3/CodexPlusPlus","slug":"canvas-user-e65e39","errorCode":null,"errorMessage":"当前推进节点不存在","messagePattern":"当前推进节点不存在","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"tools/conversation-canvas/public/canvas.user.js","lineNumber":139,"sourceCode":"    for(const key of ['title','summary','description','status'])if(typeof n[key]!=='string'||!n[key].trim()||n[key].length>12000)throw Error('整理结果缺少节点描述');\n    if(n.parent!==null&&typeof n.parent!=='string')throw Error('整理结果父节点无效');\n    ids.add(n.id);nodes.push({id:n.id,parent:n.parent,lane:n.lane,title:n.title,summary:n.summary,description:n.description,status:n.status,sources:[...new Set(n.sources)]});\n  }\n  const roots=nodes.filter(n=>n.parent===null),byId=new Map(nodes.map(n=>[n.id,n]));\n  if(roots.length!==1||roots[0].lane!=='main')throw Error('任务树必须有且只有一个主目标根节点');\n  const checked=new Set();\n  for(const node of nodes){\n    const path=new Set();let current=node;\n    while(current&&!checked.has(current.id)){\n      if(path.has(current.id))throw Error('任务树存在循环关联');\n      path.add(current.id);\n      if(current.parent!==null&&!byId.has(current.parent))throw Error('任务树包含不存在的父节点');\n      current=current.parent===null?null:byId.get(current.parent);\n    }\n    for(const id of path)checked.add(id);\n  }\n  const currentNodeId=value.currentNodeId??null;\n  if(currentNodeId!==null&&!byId.has(currentNodeId))throw Error('当前推进节点不存在');\n  return {schemaVersion:2,currentNodeId,nodes};\n}\n\nfunction parseOrganization(text,messages,requestId) {\n  const blocks=[...text.matchAll(/```(?:json)?\\s*([\\s\\S]*?)```/g)].map(m=>m[1]);\n  for(const raw of [...blocks,text.trim()]){\n    let value;try{value=JSON.parse(raw);}catch{continue;}\n    if(value?.requestId===requestId)return validateOrganization(value,messages,requestId);\n  }\n  throw Error('侧边对话未返回可识别的整理结果');\n}\n\n\nconst messageHashes=new WeakMap();\nasync function messageDigest(message){\n  const cached=messageHashes.get(message);\n  if(cached?.text===message.text)return cached.digest;\n  const bytes=new TextEncoder().encode(`${message.role}\\n${message.phase||''}\\n${message.text}`);","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/tools/conversation-canvas/public/canvas.user.js#L121-L157","documentation":"validateOrganization throws this when the result's `currentNodeId` (or the provided `currentNodeId` field) is non-null but does not match any node ID in the validated tree. The 'current' pointer must always point at an existing node.","triggerScenarios":"The model sets `currentNodeId` to an ID it did not include in `nodes`, or omits a node that the current pointer references, during parseOrganization.","commonSituations":"The model advances the current node to a planned-but-not-yet-created node, or renames IDs while forgetting to update currentNodeId.","solutions":["Set currentNodeId to an ID present in the nodes array","Set currentNodeId to null if there is no current node","Re-run the organize request reminding the model that currentNodeId must reference an existing node","Verify the ID spelling matches a node id exactly"],"exampleFix":"// before\n\"currentNodeId\":\"n-future\"  // not in nodes\n// after\n\"currentNodeId\":\"n2\"  // existing node","handlingStrategy":"validation","validationCode":"if (value.currentNodeId != null && !value.nodes.some(n => n.id === value.currentNodeId)) console.warn('currentNodeId missing from nodes');","typeGuard":"function currentNodeExists(value) { return value?.currentNodeId == null || value.nodes?.some(n => n.id === value.currentNodeId); }","tryCatchPattern":"try { org = parseOrganization(text, messages, requestId); } catch (e) { if (e.message.includes('当前推进节点不存在')) { value.currentNodeId = null; org = parseOrganization(JSON.stringify(value), messages, requestId); } else throw e; }","preventionTips":["Remind the model that currentNodeId must equal an existing node id or null","Sanitize: null out currentNodeId when it points to a removed node","Keep node renames and currentNodeId updates in the same response"],"tags":["validation","reference-integrity","llm-output"],"backgroundTag":"record-not-found","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}