gitstalk
Docs: Troubleshooting

Troubleshooting live

Find the message you saw, read what it means, do the fix. Entries are in the order you meet them: a push, its verdict, then checks, Actions, agents and setup. Message text is quoted as Gitstalk prints it; bean names and paths in it are examples.

Verdicts on a push

remote: gitstalk: RED

remote: gitstalk: RED: tax-in-total was not landed. Merged onto the sprout, these tests failed:
remote: gitstalk:   - test/discount.test.js
remote: gitstalk: it collided with these landed beans (accepted behaviour; keep both):
remote: gitstalk:   - add-discount "Add percentage discounts"
remote: gitstalk:     intent: discounted(items, rate) takes rate off the cart total.
remote: gitstalk: fix: git fetch origin sprout && git rebase origin/sprout
remote: gitstalk:      then fix, commit and git push -f origin HEAD:refs/heads/bean/tax-in-total
remote: gitstalk:      and keep working; git push -o bean=tax-in-total origin HEAD:refs/wait/any waits for its next verdict

Cause. Gitstalk merged your change onto the current sprout and ran the whole suite on that tree, and the tests listed failed. The beans listed under "collided" landed behaviour you must keep, with their intent. If no beans are listed, the fault may be in your change alone, or the sprout itself may be red: ask bean_status with checks: true, which flags failures inherited from the sprout. Failing output lines, when there are some, follow the list.

Fix. Run the fix: lines: rebase on origin/sprout, change your code to fit both behaviours, commit, and force-push the same bean branch. The new head is checked again. Force-push after a rebase is expected. More in Git compatibility.

remote: gitstalk: CONFLICT

remote: gitstalk: CONFLICT: tax-in-total does not merge onto the sprout. Conflicts in: src/cart.ts
remote: gitstalk:   <<<<<<< sprout
remote: gitstalk:   ...the sprout's side...
remote: gitstalk:   =======
remote: gitstalk:   ...your side...
remote: gitstalk:   >>>>>>> your bean
remote: gitstalk: fix: git fetch origin sprout && git rebase origin/sprout

Cause. Another bean changed the same lines and landed first. The message quotes up to 40 lines of the conflicting hunks and who wrote the sprout's side.

Fix. Rebase on origin/sprout, resolve the hunks keeping the sprout's intent, and force-push the bean as above.

PARKED (it needs a person) and DROPPED

remote: gitstalk: PARKED (it needs a person): tax-in-total: <the reason>
remote: gitstalk: decision card D-3: the bean's spec contradicts add-discount; a person decides which behaviour stays

Cause. The engine will not land this bean on its own. The reason after the bean's name says why. A decision card means two beans disagree about behaviour and a person has to choose. DROPPED means the engine gave up on it; its reason is printed the same way.

Fix. A parked or dropped bean takes no more pushes ("push the work again as a new bean"). Read the reason, then push the work under a new bean name. For a decision card, a person with the right role decides; see Decision cards and reconcile.

awaiting approval by a person

remote: gitstalk: approval rules: api -> card (policy)
remote: gitstalk: awaiting a person's approval

This bean is routed to a person: class api, decided by policy.
Nothing in it needs fixing for this. An owner or maintainer approves this revision with Approve on the
bean's page (Changes, Held), or has their agent call bean_approve. The approval re-submits it and its
check runs again. A new push needs a new approval. Agents: ask your person; never approve your own bean.

The push prints the first two lines. The paragraph below them is the bean's check output: the bean is marked red as awaits approval by a person until it is approved.

A wait (git push -o bean=<name> origin HEAD:refs/wait/any) reports the bean as held, never red: your beans: <name> (held) and next: ask your person to approve <name> on its page; do not push it again. A new push would be judged again and need a new approval.

Cause. The repository's approval rules send this kind of change to a person before it lands. Your code is fine.

Fix. Do not change the code for this. An owner or maintainer opens the bean from the repository's Changes list (it carries a Held badge, and the Held filter lists every held bean) and presses Approve in the Held panel, or asks their agent to call bean_approve. Its check then runs again and it lands if it passes. The approval is for this revision only; a new push needs a new approval. If you only have the write role, ask a maintainer: the panel says who can approve. An agent is refused when it tries to approve a bean it may have pushed itself, unless its person confirmed it (confirm_owner_intent). beta The approve controls are tested but not yet confirmed on the hosted service. To stop a rule holding your changes, an owner or maintainer can change the rules in the repository's Settings, Approval rules. See Approving a held bean.

recheck against beans that landed after it forked

remote: gitstalk: approval rules: checkout -> recheck (clef, p=0.66)
remote: gitstalk: back to its author: recheck against price-dollars
remote: gitstalk: RED: shipping was not landed. Merged onto the sprout, these tests failed:
remote: gitstalk:   - .gitstalk/policy.yml > recheck against beans that landed after it forked
remote: gitstalk:     price-dollars: Price in dollars, not cents
remote: gitstalk:       imports: src/checkout.mjs -> src/price.mjs
remote: gitstalk:       it changed, you use: price
remote: gitstalk:     Intent-checked: price-dollars

Cause. The repository triages code changes, and Clef read your bean's intent beside a bean you never saw: one that landed after you forked, or one pushed before yours and still being checked (marked pushed before this one, still being checked). It thinks the two may disagree about something both rely on, such as a unit, a format or a value, in a way neither bean's tests would show. This is not a person's hold, and no test of yours failed.

Fix. Read the named bean: git log origin/sprout for a landed one, git fetch origin bean/<name> for one in flight. If the two disagree, change your bean so both intents hold (in the example, shipping in dollars because price() now returns dollars), and add a test for the combination if you can. If a test of theirs only pins the old assumption (it expects price() + 500 in cents), update it so their intent still holds (price() * 100 + 500) and say so in your commit message. Either way, rebase on origin/sprout and push again with a trailer in the commit message naming what you checked: Intent-checked: price-dollars. That takes the bean off the list and your tests decide. See Recheck.

changes protected paths ... refused

remote: gitstalk: changes protected paths (data/schema.json): refused for @ada (write, with a deploy token)

This bean changes protected paths: data/schema.json.
The sprout protects .gitstalk/checks.yml, .gitstalk/checks.yaml, .gitstalk/checks.toml, .beanstalk/checks.yml, .beanstalk/checks.yaml, .beanstalk/checks.toml, .gitstalk/policy.yml, .beanstalk/policy.yml, data/schema.json, migrations/** (protected-paths in the checks file; the checks and policy files always).
Only the owner or a maintainer, pushing with a personal token or an SSH key, may change them;
this push was by @ada (write, with a deploy token).
Drop those changes from the bean, or ask a maintainer to push them.

Cause. The repository lists those paths in protected-paths, and every checks file (.gitstalk/checks.yml and its fallbacks) and .gitstalk/policy.yml are always protected. The bean's check goes red with "changes a protected path". Only an owner or maintainer using their own personal token or SSH key may change them. Agent sessions, deploy tokens and engine tokens never can, whoever they act for.

Fix. Drop those changes from the bean, or have a maintainer push them. See Checks: protected paths.

! [remote rejected]

Refusals happen inside the git protocol, so git prints a normal rejected line, followed by remote: gitstalk: push refused: <reason>. The reason is one of these:

You pushed The reason says Do this
sprout, stalk or main refs/heads/sprout is the engine's: landing is never a push. Push your work to refs/heads/bean/<name>; it lands when its pre-land check is green Push to refs/heads/bean/<name>.
A tag, or any branch that is not bean/* only beans are pushed: refs/heads/bean/<name> (letters, digits, . _ -; up to 32), not refs/tags/v1 Name the branch bean/<name>. Tags are not accepted.
A deletion deleting refs is not allowed Do not delete; a bean ends by landing or being dropped.
Two beans in one push push one bean at a time (one refs/heads/bean/<name> per push) Push them separately.
A new commit to a bean still in check bean tax-in-total is being checked (push 1, 3f9a1c2); its verdict comes first. Wait for it with git push -o bean=tax-in-total origin HEAD:refs/wait/any (returns at the verdict), then push again if it is red or in conflict; a landed bean takes new work as a new bean Wait for the verdict, then push again if it is red or in conflict.
A bean that already landed bean tax-in-total already landed; push new work as a new bean (refs/heads/bean/<new-name>) Use a new bean name.
A parked or dropped bean bean tax-in-total is parked (<reason>); push the work again as a new bean Use a new bean name.
Anything while the repository engine is not running the repository engine is <phase> Try again later; ask the owner if it persists.

Some refusals name a role or a credential instead: your role on this repository is read; to push beans you need the write role, <owner>'s repository is public to read; to push beans ask its owner for the write role, this token may not push beans here (read-only access) and this credential may not push beans (its scopes do not include it). Ask an owner for the write role (collaborators) or use a token with the write scope.

The push hangs

Cause. You pushed with -o wait or to a wait ref, which holds the connection until the verdict. That is the feature, not a stall: you see progress lines, and a keepalive every 15 seconds.

Command Waits up to
git push -o wait ... 600 s by default; -o wait=<seconds> up to 1,800 s
git push origin HEAD:refs/wait/any (or all) 540 s by default, under the 10-minute limit of an agent's shell tool
MCP bean_wait 300 s by default; timeout_s up to 1,800 s

Fix. If you do not want to wait, push without options: it returns as soon as the bean is received. If the wait ran out, the push says where the verdict will be: git cat-file -p refs/beans/<name>/status after git fetch origin '+refs/beans/*:refs/beans/*'. Never poll with sleep in a loop; one blocking call wakes on the verdict. See Waiting without polling.

Access

404 on a repository you know exists

Cause. A repository you may not see answers 404, exactly as a missing one does. It is private and you have no role on it, or you are signed in as a different account. A repository that was renamed or moved keeps its old address, and git prints gitstalk: this repository moved to <owner>/<name>; the old address keeps working.

Fix. Check you are signed in as the right account, and ask an owner to add you (collaborators and visibility). For a moved repository, run git remote set-url origin <new url>.

git is not connected to your account

Gitstalk: this git is not connected to your account yet. Pick one:
  1. Claude Code (easiest): /gitstalk:setup
     not installed? claude plugin marketplace add coop-collective/gitstalk-plugin && claude plugin install gitstalk@gitstalk
  2. HTTPS: make a token at https://<gitstalk host>/settings/tokens and paste it at git's password prompt
  3. CI and scripts: a deploy token in GITSTALK_TOKEN (the repository page, tab "Env vars")

Cause. No credential reached Gitstalk, or git was given one that was refused (that credential was refused (expired, revoked, or not for this repository)). Fix. Pick one of the three ways. See Accounts, tokens and keys and the setup script.

SSH does not work

Cause. Git over SSH is planned: it is built and tested, but not public. You can register an SSH key (it approves your machine), but git remotes use HTTPS today. Fix. Clone with https://<host>/<owner>/<repo>.git. /gitstalk:setup stores an HTTPS token for you.

Checks and Actions

.gitstalk/checks.yml is invalid

.gitstalk/checks.yml on the merged tree is invalid, so no tests ran:
  line 3, column 1: unknown key "command": checks.yml spells it "run"
Fix the file in this bean; see /docs/checks for the format.

Cause. The file is read from the exact merged tree and any problem is red without running a test. Each problem gives its line, column and key (an older checks.toml names the key, and the line and column of a syntax error). Fix. Correct the file in the same bean. The format is in Checks.

The check says it only runs node

line 1, column 8: image: "python" is not available: the runner image ships Node 25.8.1 only, so the one image is "node" (see /docs/checks)
line 2, column 6: run: must start with "node": the runner reads node's test reporter (other test runners need another image; see /docs/checks)
line 2, column 6: run: must run node --test

Cause. Checks run node --test in one image today, with nothing installed at check time. run is a list of arguments, never a shell, so npm test is refused. Fix. Use a command such as run: [node, --test, "spec/**/*.spec.mjs"]. Other languages and test runners are not supported yet.

Actions minutes for the month are spent

this repository's 100 Actions minutes for the month are spent
this repository's 100 Actions minutes for the month are used

Cause. The repository used its monthly Actions minutes on the managed beta (100 there; the number in the message is the limit). A run that starts by itself ends as a startup failure with the first message, never a red run. Starting one by hand (run, re-run or an automation's run now) is refused with the second message. Fix. Wait for the next month, or self-host and set ACTIONS_MONTHLY_MINUTES. See Limits and plans.

My workflow did not start

Cause. Gitstalk runs push (a bean reaching the stalk is a push to main), workflow_dispatch and schedule. pull_request, merge_group, repository_dispatch, workflow_run and workflow_call are marked as never running. Fix. Open the repository's Automations tab and its Actions view: each workflow lists its triggers and whether they run, with notes on what runs differently here. Move the job to a push trigger, or run it by hand. See GitHub Actions.

A secret is empty in a bean's run

Cause. Pre-land runs of a bean pushed by an agent session, a deploy token or a collaborator below maintain get no secrets unless the secret is marked Available to pre-land checks, because a bean is unreviewed code. Runs of the stalk, dispatches and schedules get them as usual. Fix. Switch the secret on for pre-land checks only if you accept that risk, or move the step to a run after landing. See Secrets and variables.

Agents and names

My agent has no write tool, or no secrets tool

Cause. The server offers only the tools a session's scopes allow. Without write there is no tool that opens beans, commits, claims tasks or starts runs; without secrets there are no secret tools. Your role on the repository is also checked on every call. Fix. Reconnect the agent and tick the scope (secrets is never ticked for you). See MCP tools and scopes. If the tools seem to have older names, see names that changed.

Old beanstalk names

Cause. Gitstalk was called Beanstalk until 10 October 2026. What still works. BEANSTALK_WEB, BEANSTALK_NO_BROWSER and the other BEANSTALK_* settings are read when the GITSTALK_* one is unset; .beanstalk/checks.yml (or checks.toml) and .beanstalk/automations/ are read when there is no .gitstalk/ file; and an old plugin install keeps working after you update it. See upgrading.

Sources