3.2 KiB
name, description
| name | description |
|---|---|
| gitea-merge-form-encoded | Use when a Gitea API merge on Dankclaw (192.168.0.143:3000) returns HTTP 422 "[Do]: Required" — the merge endpoint needs form-encoded fields with the lowercase field name do, not the JSON body that PR creation accepts. |
Gitea on Dankclaw (192.168.0.143:3000) — merge quirk, measured 2026-10-19 on dank/serverAppConfigs and again on dank/dankvoice.
Creating a PR accepts a JSON body. Merging does not: POST /api/v1/repos/{owner}/{repo}/pulls/{n}/merge with a JSON body ({"merge_style":"no-ff", ...}) or with those values as request headers returns 422 {"message":"[Do]: Required"} — four variants of that all fail identically, so do not "fix" it by changing the style name or moving the headers around.
The field name is lowercase do. --data-urlencode 'Do=merge' (capital D, which the error message spells) returns the same 422 [Do]: Required. Do not retry with case variants — the web-UI form field is do.
Working call (form-encoded):
tok=$(sed -n 's|http://[^:]*:\([^@]*\)@.*|\1|p' ~/.config/secrets/gitea | head -1) # git credential.helper store file
curl -sS -X POST -w 'http %{http_code}\n' -K <(printf 'header = "Authorization: token %s"\n' "$tok") \
--data-urlencode 'do=merge' \
--data-urlencode 'merge_style=no-ff' \
http://192.168.0.143:3000/api/v1/repos/dank/<repo>/pulls/<N>/merge
# 200 with an empty body == merged
merge_stylevalues are the dashed names:no-ff,merge,rebase,squash.- Keep the token out of argv:
-K <(printf …)feeds theAuthorizationheader through stdin (a-H "Authorization: token …"lands in/proc/<pid>/cmdline, world-readable — the 2026-09-16 HF-token leak class). - Verify by fast-forwarding a checkout (
git fetch && git merge --ff-only origin/main) rather than re-reading the PR. - Fleet law still applies: never merge without an explicit current OK from Frank, and open the PR URL in his browser (
xdg-open) the moment it exists.
Credential-store token extraction (same file, adjacent trap)
~/.config/secrets/gitea holds one line shaped http://user:token@192.168.0.143:3000. Splitting it with awk -F'/' puts the host in $3, not $2, and awk -F'/' '{print $NF}' yields the host+path, not the token — an empty/garbage token makes private repos answer 404 not found (Gitea hides them from anonymous), which reads like a wrong URL rather than an auth failure. Extract with:
tok=$(sed -n 's|^https\{0,1\}://[^:]*:\([^@]*\)@192\.168\.0\.143.*$|\1|p' ~/.config/secrets/gitea | head -1)
echo "token length: ${#tok}" # 40 — print the length, never the value
Other API quirks measured the same day:
GET /pulls?state=opencan return an error object wherestate=allreturns the list;state=alllist entries may omithead/base— fetch/pulls/{n}for those.- POST
/pullsfor a head/base pair that already has a PR →409namingissue_id: N; the PR number is thatissue_id, so PATCH it instead of POSTing again. - Issues and PRs share the issue index per repo, so
#36-style numbers are repo-scoped: a footer fix aimed atdank/command-center#36404s when pointed atdank/dankvoice.