BigPizzaV3/CodexPlusPlus · error

当前推进节点不存在

Error message

当前推进节点不存在

What it means

The organization result carries an optional `currentNodeId` marking which node is currently in progress; it defaults to null when absent. If provided, it must match one of the validated node ids; otherwise the validator throws because the pointer would reference a nonexistent node.

Solutions

  1. Verify currentNodeId appears exactly (string equality, case-sensitive) among the node ids in the JSON.
  2. Retry the organize call asking the model to set currentNodeId to one of the listed node ids, or to omit it for null.
  3. If no node is meaningfully 'current', drop the field so it defaults to null.
  4. When post-processing, clamp currentNodeId to an existing id before calling parseOrganization.

Example fix

// before
{"nodes":[{"id":"n1",...}],"currentNodeId":"n2"}
// after
{"nodes":[{"id":"n1",...}],"currentNodeId":"n1"}
Defensive patterns

Strategy: validation

Validate before calling

function currentNodeExists(org){ const cn=org?.currentNodeId; return cn==null || (org?.nodes||[]).some(n=>n?.id===cn); }

Type guard

function isValidCurrentNode(cn, nodes){ return cn === null || cn === undefined || (Array.isArray(nodes) && nodes.some(n => n?.id === cn)); }

Try / catch

try { const org = parseOrganization(text, messages, requestId); } catch (e) { if (e.message === '当前推进节点不存在') { /* clamp currentNodeId to an existing id or null and retry */ } else throw e; }

Prevention

When it happens

Trigger: The model returns {"currentNodeId":"n42",...} while nodes only contain other ids; the id casing or prefix differs ("N1" vs "n1"); currentNodeId points at a node removed in a later revision while the pointer was stale. Check: `currentNodeId!==null&&!byId.has(currentNodeId)`.

Common situations: Model hallucinates a current node id not in its own list; the id numbering restarted mid-response; an edited/trimmed node list kept an old currentNodeId; prompt templates with placeholder ids leaked into output.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19). Data as JSON: /api/errors/14d351b24d6b16db. Report an issue: GitHub.

Appendix: source

Thrown at tools/conversation-canvas/organize.mjs:36

    for(const key of ['title','summary','description','status'])if(typeof n[key]!=='string'||!n[key].trim()||n[key].length>12000)throw Error('整理结果缺少节点描述');
    if(n.parent!==null&&typeof n.parent!=='string')throw Error('整理结果父节点无效');
    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)]});
  }
  const roots=nodes.filter(n=>n.parent===null),byId=new Map(nodes.map(n=>[n.id,n]));
  if(roots.length!==1||roots[0].lane!=='main')throw Error('任务树必须有且只有一个主目标根节点');
  const checked=new Set();
  for(const node of nodes){
    const path=new Set();let current=node;
    while(current&&!checked.has(current.id)){
      if(path.has(current.id))throw Error('任务树存在循环关联');
      path.add(current.id);
      if(current.parent!==null&&!byId.has(current.parent))throw Error('任务树包含不存在的父节点');
      current=current.parent===null?null:byId.get(current.parent);
    }
    for(const id of path)checked.add(id);
  }
  const currentNodeId=value.currentNodeId??null;
  if(currentNodeId!==null&&!byId.has(currentNodeId))throw Error('当前推进节点不存在');
  return {schemaVersion:2,currentNodeId,nodes};
}

export function parseOrganization(text,messages,requestId) {
  const blocks=[...text.matchAll(/```(?:json)?\s*([\s\S]*?)```/g)].map(m=>m[1]);
  for(const raw of [...blocks,text.trim()]){
    let value;try{value=JSON.parse(raw);}catch{continue;}
    if(value?.requestId===requestId)return validateOrganization(value,messages,requestId);
  }
  throw Error('侧边对话未返回可识别的整理结果');
}

View on GitHub (pinned to b1ed92e5e4)