{"record":{"id":"1a5f297fe62d18a4","repo":"TencentCloud/TencentDB-Agent-Memory","slug":"skill-get-failed-getenv-code","errorCode":null,"errorMessage":"skill get failed: ${getEnv.code}","messagePattern":"skill get failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"MemoryPanel/src/panel/http/routes/meta/proxy.ts","lineNumber":356,"sourceCode":"}\n\n/** fork skill 到目标 agent（get → files/read → create），复用前端 forkToAgent 的语义。 */\nasync function forkSkillToAgent(\n  deps: PanelDeps,\n  ctx: MetaCallContext,\n  userId: string,\n  teamId: string,\n  sourceSkillId: string,\n  targetAgentId: string,\n): Promise<void> {\n  const getEnv = await deps.skillKernel.invoke('get', {\n    user_id: userId,\n    team_id: teamId,\n    skill_id: sourceSkillId,\n    include_content: true,\n    include_manifest: true,\n  }, ctx);\n  if (getEnv.code !== 0) throw new Error(`skill get failed: ${getEnv.code}`);\n  const detail = getEnv.data as {\n    name: string;\n    content: string;\n    manifest?: Array<{ path: string; is_executable?: boolean }>;\n  };\n\n  const resources: Array<{\n    path: string;\n    content: string;\n    encoding: string;\n    mime_type?: string;\n    is_executable?: boolean;\n  }> = [];\n  for (const entry of detail.manifest ?? []) {\n    try {\n      const fEnv = await deps.skillKernel.invoke('files/read', {\n        user_id: userId,\n        team_id: teamId,","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/3efcd317b84146d6a08518ac0f7ee7c8a8d200ec/MemoryPanel/src/panel/http/routes/meta/proxy.ts#L338-L374","documentation":"forkSkillToAgent fetches the source skill's full detail (content + manifest) via an internal skill 'get' command executed in a forked environment. The command returns an envelope with a code; any non-zero code means the fetch failed, and the function throws with that code so the fork (cloneTemplateAssets) aborts before creating the copy.","triggerScenarios":"Forking a skill whose skill_id does not exist, belongs to another user/team without access, or whose backend 'get' call fails (include_content/include_manifest request rejected).","commonSituations":"Forking from a template skill that was deleted; cross-team skill fork without permission; transient backend error surfacing as a non-zero exit code; stale sourceSkillId after skill deletion.","solutions":["Log/inspect getEnv.code and the underlying env stderr to identify the actual failure (404 vs permission)","Verify sourceSkillId exists and is accessible to user_id/team_id before forking","Refresh the source skill id from the skill list API","Retry on transient backend failures; abort the fork for permanent codes"],"exampleFix":"// before\nif (getEnv.code !== 0) throw new Error(`skill get failed: ${getEnv.code}`);\n// after\nif (getEnv.code !== 0) {\n  logger.error(`skill get failed: code=${getEnv.code} stderr=${getEnv.stderr}`);\n  throw new Error(`skill get failed: ${getEnv.code} (${getEnv.stderr ?? 'no detail'})`);\n}","handlingStrategy":"try-catch","validationCode":"const exists = await skillsApi.exists({ skill_id: sourceSkillId, team_id: teamId });\nif (!exists) throw new Error(`source skill ${sourceSkillId} not accessible`);","typeGuard":null,"tryCatchPattern":"try { await forkSkillToAgent(...); } catch (e) { if (e.message.startsWith('skill get failed:')) { logger.error(`cannot read source skill (${e.message}); check skill_id and permissions`); } else throw e; }","preventionTips":["Verify sourceSkillId exists and the user/team has read access before forking","Include the env's stderr/detail when surfacing error codes","Handle deleted skills gracefully in template fork flows"],"tags":["skill-fork","ipc","error-code"],"backgroundTag":"subcommand-nonzero-exit","analyzedSha":"3efcd317b84146d6a08518ac0f7ee7c8a8d200ec","analyzedAt":"2026-09-01T05:44:22.276Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}