You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用GitHub API创建Issue返回HTTP 400 Bad Request错误

问题现象

编写push操作完成后自动创建Issue的自动化脚本时,GitHub API返回400错误,完全相同的代码此前可正常运行,无法定位问题出在代码逻辑还是API规则层面。

原实现代码
for ((i=0;i<${#arr_libraryNames[@]};++i))
do 
    httpResponse=$(\
                    curl \
                    -H "Authorization: token ${OAuthToken}"\
                    https://api.github.com/repos/tpazhaidam/${arr_libraryNames[i]}/issues\
                    -d "{\"title\":\"Library Requires Template Update\",\"body\":\"When possible please update libraries to the most recent template version.\",\"assignees\":[\"tpazhaidam\"],\"labels\":[\"template update\"]}"\
                    -H "Accept: $API_VER_ACCEPTS"\
                    -X POST\                
                    )

    if [ "$httpResponse" != "201" ]; then
        echo "Failed to create issue for ${arr_libraryNames[i]} on GitHub"
        echo "HTTP Response $httpResponse"
        exit 1
    else
        echo "OK"
    fi                  
done 
收到的HTTP错误响应
HTTP Response
<html>
  <head>
    <meta content="origin" name="referrer">
    <title>Bad request &middot; GitHub</title>
    <meta name="viewport" content="width=device-width">
    <style type="text/css" media="screen">
      body {
        background-color: #f6f8fa;
        color: rgba(0, 0, 0, 0.5);
        font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
        font-size: 14px;
        line-height: 1.5;
      }
      .c { margin: 50px auto; max-width: 600px; text-align: center; padding: 0 24px; }
      a { text-decoration: none; }
      a:hover { text-decoration: underline; }
      h1 { color: #24292e; line-height: 60px; font-size: 48px; font-weight: 300; margin: 0px; }
      p { margin: 20px 0 40px; }
      #s { margin-top: 35px; }
      #s a {
        color: #666666;
        font-weight: 200;
        font-size: 14px;
        margin: 0 10px;
      }
    </style>
  </head>
  <body>
    <div class="c">
      <h1>Whoa there!</h1>
      <p>You have sent an invalid request. <br><br>
        Please do not send this request again.
      </p>
      <div id="s">
        <a href="https://support.github.com">Contact Support</a> &mdash;
        <a href="https://githubstatus.com">GitHub Status</a> &mdash;
        <a href="https://twitter.com/githubstatus">@githubstatus</a>
      </div>
    </div>
  </body>
</html>
问题根因

三个问题直接触发400拦截,都是早期API校验宽松时可正常运行、近期校验规则收紧后直接报错的典型情况:

  • 响应判断逻辑从根上错了:当前代码把curl输出的完整响应正文存在httpResponse变量里,却拿它和HTTP状态码201做对比。curl默认不会输出HTTP状态码,变量里存的永远是接口返回的正文内容,永远不可能匹配上"201",之前能正常运行大概率是旧版本脚本加了状态码提取参数,后续修改时被误删了。
  • 缺少必填请求头:调用GitHub创建Issue接口传输JSON数据时,必须显式携带Content-Type: application/json请求头。现在GitHub API对请求格式校验比之前严格,缺这个头的请求会直接被边缘防护拦截,返回通用400 HTML错误页,不会返回结构化的JSON错误信息,很难直接定位问题。
  • shell语法存在隐性bug:原代码里-X POST\这一行的反斜杠后面带了多余的空格,shell中行尾用于续行的反斜杠后不能跟任何空格、制表符,否则转义失效,后面的参数会被截断,直接导致请求格式非法。另外手动转义JSON双引号的写法容错率极低,只要传入的仓库名、参数里带特殊字符、空格,就会导致JSON格式错误。
修正后的可运行代码
for ((i=0;i<${#arr_libraryNames[@]};++i))
do 
    # 用here-document定义JSON载荷,无需手动转义双引号,避免格式错误
    issue_payload=$(cat <<EOF
{
    "title": "Library Requires Template Update",
    "body": "When possible please update libraries to the most recent template version.",
    "assignees": ["tpazhaidam"],
    "labels": ["template update"]
}
EOF
)
    # 发请求:-s静默输出进度条,-w单独提取HTTP状态码做判断,加必填的Content-Type头,响应正文存入临时文件方便排查
    http_code=$(curl -s -w "%{http_code}" \
                    -H "Authorization: token ${OAuthToken}" \
                    -H "Accept: ${API_VER_ACCEPTS}" \
                    -H "Content-Type: application/json" \
                    -d "$issue_payload" \
                    -X POST \
                    "https://api.github.com/repos/tpazhaidam/${arr_libraryNames[i]}/issues" \
                    -o /tmp/github_issue_resp.tmp)

    if [ "$http_code" != "201" ]; then
        echo "Failed to create issue for ${arr_libraryNames[i]} on GitHub"
        echo "HTTP Status Code: $http_code"
        echo "Error response content:"
        cat /tmp/github_issue_resp.tmp
        rm -f /tmp/github_issue_resp.tmp
        exit 1
    else
        echo "Created issue for ${arr_libraryNames[i]} successfully"
        rm -f /tmp/github_issue_resp.tmp
    fi                  
done
额外注意点
  • 所有行尾用于续行的反斜杠后面不要加任何空格,写完直接敲回车换行即可,避免转义失效。
  • 如果个人访问令牌(OAuthToken)是新生成的,要确认勾选了repo范围的权限,否则也会出现请求被拦截的情况。

内容的提问来源于stack exchange,提问作者Thomas Pazhaidam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:01:10