Found by a blind dogfood run against v0.1.90-21-gf56aa72.
Symptom
--print-input is documented as making no request at all, but it refuses to run without a credential.
The README hands this to newcomers as copy-pasteable:
civitai generate "a cat" --quantity 2 --aspect-ratio 1:1 --print-input > graph.json
annotated "No submit, no cost estimate, no balance read — with no --checkpoint/--lora, no request at all." The command table repeats it: "prints the assembled graph and exits without reaching any money seam."
What actually happens with no credential:
$ XDG_CONFIG_HOME=/tmp/empty civitai generate "a cat" --print-input > graph.json ; echo $?
Error: no token configured — generation needs a credential with the AI Services scopes […]
3
$ wc -c graph.json
0 graph.json
The gate is premature, not a real request — measured
With a garbage token it succeeds, fully offline. A junk credential would 401 if any request were actually made:
$ CIVITAI_TOKEN=not-a-real-token-000 civitai generate "a cat" --print-input ; echo $?
{
"workflow": "txt2img",
"prompt": "a cat",
…
}
0
So the auth check runs before the --print-input short-circuit, and the credential is never used for anything.
Why it matters
This is the one generate surface an un-onboarded user can explore with zero risk — "what does a generation graph even look like?" — and it is the one gated behind the credential they do not yet have. It is also the documented starting point for building an --input document, so the recommended on-ramp to the feature is closed to exactly the people who need it.
The README makes a specific promise here and the binary does not keep it. Either the code or the docs is wrong; the code looks wrong, because the offline path demonstrably works.
Suggested fix
Move the credential check after the --print-input branch, so the short-circuit is reached first. Keep the check ahead of every path that does reach a seam.
Note the one genuine exception, which must not regress: per AGENTS.md item 19(f), --print-input with --image does upload local files (it must emit a document --input can submit, which means real blob URLs). That path needs a credential and should keep requiring one — so the gate becomes conditional on --image/--checkpoint/--lora rather than unconditional. --print-input with none of those is the free, offline case the docs describe.
Test coverage this needs
--print-input with no credential and no --image/--checkpoint/--lora → exit 0, valid JSON on stdout, no network (assert against a seam that would fail loudly if dialled, not by observing that it happened to work).
--print-input --image <local file> with no credential → still refused (positive control; otherwise "delete the gate" passes).
--dry-run with no credential → unchanged (it does reach the estimate seam).
- Assert the exit code with
errors.Is, not message text.
Found by a blind dogfood run against
v0.1.90-21-gf56aa72.Symptom
--print-inputis documented as making no request at all, but it refuses to run without a credential.The README hands this to newcomers as copy-pasteable:
annotated "No submit, no cost estimate, no balance read — with no
--checkpoint/--lora, no request at all." The command table repeats it: "prints the assembled graph and exits without reaching any money seam."What actually happens with no credential:
The gate is premature, not a real request — measured
With a garbage token it succeeds, fully offline. A junk credential would 401 if any request were actually made:
So the auth check runs before the
--print-inputshort-circuit, and the credential is never used for anything.Why it matters
This is the one
generatesurface an un-onboarded user can explore with zero risk — "what does a generation graph even look like?" — and it is the one gated behind the credential they do not yet have. It is also the documented starting point for building an--inputdocument, so the recommended on-ramp to the feature is closed to exactly the people who need it.The README makes a specific promise here and the binary does not keep it. Either the code or the docs is wrong; the code looks wrong, because the offline path demonstrably works.
Suggested fix
Move the credential check after the
--print-inputbranch, so the short-circuit is reached first. Keep the check ahead of every path that does reach a seam.Note the one genuine exception, which must not regress: per
AGENTS.mditem 19(f),--print-inputwith--imagedoes upload local files (it must emit a document--inputcan submit, which means real blob URLs). That path needs a credential and should keep requiring one — so the gate becomes conditional on--image/--checkpoint/--lorarather than unconditional.--print-inputwith none of those is the free, offline case the docs describe.Test coverage this needs
--print-inputwith no credential and no--image/--checkpoint/--lora→ exit 0, valid JSON on stdout, no network (assert against a seam that would fail loudly if dialled, not by observing that it happened to work).--print-input --image <local file>with no credential → still refused (positive control; otherwise "delete the gate" passes).--dry-runwith no credential → unchanged (it does reach the estimate seam).errors.Is, not message text.