{"record":{"id":"f65248e802e85c35","repo":"tinyhumansai/openhuman","slug":"gh-issue-comment-failed-r-stderr-trim","errorCode":null,"errorMessage":"gh issue comment failed: ${r.stderr?.trim() || \"\"}","messagePattern":"gh issue comment failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/agent-batch/status.mjs","lineNumber":160,"sourceCode":"    .map((line) => line.trim())\n    .filter((line) => line.length > 0)\n    .map((line) => JSON.parse(line));\n  if (existing.length === 0) {\n    const r = spawnSync(\n      \"gh\",\n      [\n        \"issue\",\n        \"comment\",\n        String(issue),\n        \"--repo\",\n        spec.base_repo,\n        \"--body-file\",\n        \"-\",\n      ],\n      { encoding: \"utf8\", input: body },\n    );\n    if (r.status !== 0) {\n      throw new Error(`gh issue comment failed: ${r.stderr?.trim() || \"\"}`);\n    }\n    process.stdout.write(\n      `[agent-batch] posted new tracking comment on #${issue}\\n`,\n    );\n  } else {\n    const id = existing[0].id;\n    // Pass the comment body via stdin (-F body=@-) rather than a command-line\n    // arg. Long markdown tables can grow large and -f body=${body} risks\n    // hitting OS argv length limits (ARG_MAX).\n    const r = spawnSync(\n      \"gh\",\n      [\n        \"api\",\n        \"--method\",\n        \"PATCH\",\n        `repos/${spec.base_repo}/issues/comments/${id}`,\n        \"-F\",\n        \"body=@-\",","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/agent-batch/status.mjs#L142-L178","documentation":"postOrUpdateTrackingComment() in scripts/agent-batch/status.mjs posts a brand-new tracking comment via `gh issue comment <N> --repo <repo> --body-file -` (body piped on stdin) and throws with gh's stderr when the child exits non-zero. This branch only runs when the earlier gh api comment listing found zero comments containing the batch marker — i.e. the first --post for this batch.","triggerScenarios":"First --post run for a batch when: the account has no write/comment permission on tinyhumansai/openhuman (403/404), the tracking issue is locked, the token is read-only (classic read PAT or fine-grained without issues:write), or the network/rate limit rejects the POST.","commonSituations":"Contributors running the batch status tooling from forks with tokens that can read but not comment; locked/archived tracking issues; intermittent secondary rate limits when several batch agents post near-simultaneously.","solutions":["Test permission directly: `gh issue comment <N> --repo tinyhumansai/openhuman --body \"probe\"` (delete after)","Ensure the token has issues:write (fine-grained) or `public_repo`/`repo` scope (classic); re-auth if needed","Confirm the tracking issue is unlocked and open for collaborators","Re-run the command once the permission/rate-limit issue is cleared — the listing step will still find no marker comment, so it will retry the post path"],"exampleFix":"# before\n$ node scripts/agent-batch/status.mjs batch.json --post\nError: gh issue comment failed: HTTP 403: Resource not accessible by integration\n\n# after (token with issues:write)\n$ export GH_TOKEN=<token-with-issue-comment-scope>\n$ node scripts/agent-batch/status.mjs batch.json --post","handlingStrategy":"retry","validationCode":"import { spawnSync } from \"node:child_process\";\nconst who = spawnSync(\"gh\", [\"api\", \"user\", \"--jq\", \".login\"], { encoding: \"utf8\" });\nif (who.status !== 0) throw new Error(\"gh token invalid\");\nconst perm = spawnSync(\"gh\", [\"api\", `repos/tinyhumansai/openhuman/collaborators/${who.stdout.trim()}/permission`, \"--jq\", \".permission\"], { encoding: \"utf8\" });\nif (![\"write\", \"admin\"].includes(perm.stdout.trim())) throw new Error(\"token cannot comment on the tracking issue\");","typeGuard":null,"tryCatchPattern":"try {\n  await postComment(spec, body);\n} catch (e) {\n  if (/gh issue comment failed/.test(e.message) && !/40[13]/.test(e.message)) {\n    await sleep(10_000);\n    return postComment(spec, body);\n  }\n  throw e;\n}","preventionTips":["Give automation tokens issues:write scope up front — read tokens will always fail at the post step","Keep one canonical --post runner per batch to avoid concurrent first-post races"],"tags":["github","cli","auth","permissions"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}