octokit.js更新README文件的正确方法是什么?接口报NotFound如何解决
问题原因
调用octokit.repos.createOrUpdateFileContents返回HttpError: Not Found,和README文件本身的获取逻辑无关,GitHub对所有无权限访问、路径错误的资源统一返回404,不会区分是权限问题还是资源不存在。你创建随机命名文件也报同样错误,基本可以排除单文件路径写错的问题,常见触发原因如下:
- Octokit初始化时未传入有效认证token,或传入的token没有目标仓库的写入权限:个人访问令牌需要勾选
repo全部分支权限,如果是组织仓库,还要确认组织没有开启第三方应用访问限制,token已被授权访问该仓库。 - 接口传入的
owner或repo参数拼写错误:你报错里的路径是/repos/bob/repo-name/,先核对所有者用户名/组织名、仓库名的拼写和大小写,和GitHub页面显示完全一致才可以。 - 私有仓库未授权访问:如果目标仓库是私有仓库,未携带有效权限token的请求会直接返回404,不会提示无权限。
- GitHub Enterprise Server用户未配置正确的
baseUrl,请求发到了公有云GitHub服务,自然找不到企业内部的仓库。
正确调用方法
更新已有文件必须先拿到目标文件的最新SHA值,否则接口会报错,完整调用代码如下:
const { Octokit } = require("@octokit/rest"); // 初始化实例,替换成自己的有效token const octokit = new Octokit({ auth: "ghp_你的个人访问令牌", // 企业版GitHub才需要配置下面的baseUrl,公有云用户删掉这行 // baseUrl: "https://你的企业GitHub域名/api/v3" }); async function updateReadme() { // 第一步:拉取现有README的信息,拿到文件SHA const { data: currentFile } = await octokit.repos.getContent({ owner: "bob", // 替换成实际仓库所有者 repo: "repo-name", // 替换成实际仓库名 path: "README.md", }); // 第二步:把新的文件内容转成base64编码 const updatedContent = Buffer.from(`# 新的README标题 这里是更新后的README正文内容`).toString("base64"); // 第三步:提交更新 await octokit.repos.createOrUpdateFileContents({ owner: "bob", repo: "repo-name", path: "README.md", message: "docs: 更新README内容", // 对应git提交信息 content: updatedContent, sha: currentFile.sha, // 已有文件更新必须传当前SHA,创建不存在的文件时不要传这个参数 branch: "main" // 可选,不传默认提交到仓库默认分支 }); } updateReadme().catch(console.error);
快速排查步骤
- 先在浏览器直接访问报错里的接口地址,如果未登录状态下访问返回404,先确认仓库是否公开、owner和repo名是否拼写正确。
- 如果浏览器未登录能正常访问内容,优先检查Octokit初始化时传入的token权限,确认token勾选了
repo权限范围。 - 如果是要新建文件,不要传
sha参数,传了不存在的SHA值也会触发404错误。
不要死磕文件路径问题,所有场景下创建新文件也报404,优先查认证权限、仓库参数两个点,这两个问题占该报错的90%以上。
内容的提问来源于stack exchange,提问作者Nithur
相关产品推荐
相关产品推荐

