Nuvelics documentation
CLI

Exit codes and errors

Every failure the nuvelics tool can report, with its exit code, whether it is worth retrying, and what to do about it.

A command that works exits with 0. A command that fails exits with a non-zero code and reports one error of a fixed set of kinds. The exit code tells you roughly what went wrong; the kind tells you exactly, and retryable tells you whether to try again.

Exit codes

CodeMeaning
0The command succeeded.
1An unexpected failure inside the tool, or an answer from the API it could not understand.
2The command was malformed, or the tool could not act on the context or credential. For the context and credential kinds below (unknown-context, ambiguous-context, unauthenticated), nothing was sent.
3The command was well formed, but the API refused it or failed.
4The API could not be reached.

Kinds

kindExitRetry?What it means
usage2noAn unknown flag or command, a bad argument, a malformed --filter, or a missing --yes. Fix the command.
unknown-context2no--context names a context that does not exist.
ambiguous-context2noA write with no --context and no terminal. See Contexts.
unauthenticated2noThere is no credential stored for the context. A person must sign in.
forbidden3noThe API rejected the credential (a revoked or mistyped key, or a sign-in that can no longer be renewed), or the credential is valid but is not allowed to do this. If whoami returns it, a person must sign in again.
not-found3noThere is no such item.
invalid-request3noThe API rejected the request. The fields list says which fields to fix.
conflict3yesSomeone changed the item while you were working. Run the same command again.
rejected3noThe item's current state forbids this, for example approving a pitch that is already approved. Running it again will not succeed.
rate-limited3yesToo many requests. Wait, then run it again.
spend-capped3noYour organization's own spending cap has been reached. This is not a permissions problem. Raising the cap, or the cap's window rolling over, fixes it. See Spend and usage.
claim-check-blocked3noA push to your content system was held back by the output's claim check. See below.
server-error3yesA temporary failure on the server.
network4yesThe API could not be reached.
internal1noAn unexpected failure in the tool, or a malformed response.

The set is closed: every failure is exactly one of these fifteen.

Decide with retryable, not the exit code

Exit code 3 covers errors you should retry (conflict, rate-limited, server-error) and errors you should not (forbidden, not-found, invalid-request, rejected, spend-capped, claim-check-blocked). Read retryable from the error, or use the table above.

The two that look alike behave differently. conflict means the item changed under you, so the same command can succeed on a second try. rejected means a rule forbids the action in the item's present state, and it will keep failing until the state changes.

Retry only where retryable is true. Wait between attempts, and give up after a small, fixed number of them. Exit code 2 is never worth retrying unchanged.

Reading an error

With -o json, an error is a JSON object on standard error:

{"error":{"kind":"invalid-request","message":"...","exitCode":3,"retryable":false,
          "requestId":"...","fields":[{"field":"name","message":"..."}]},
 "meta":{"context":"prod","baseUrl":"https://api.nuvelics.com/api","orgId":null}}

(meta is abridged.)

  • kind, exitCode and retryable are as in the tables above.
  • fields has one entry per field to fix when the kind is invalid-request.
  • requestId, when present, identifies the call. Include it when you ask for help.
  • details appears only on kinds that carry structured data. Today that is claim-check-blocked.

Claim-check refusals

nuvelics story outputs push refuses an output whose claim check is not clear, with claim-check-blocked. Read error.details.reason, not the message text. It is one of open_findings, outdated or never_checked, and error.details.openCount is the number of open findings.

  • outdated or never_checked: ask for a check, wait for it, then push again.

    nuvelics story outputs check <story> <output> --context acme -o json
    nuvelics story outputs get <story> <output> -o json
    nuvelics story outputs push <story> <output> --context acme -o json

    check returns at once with the claim check pending. Repeat get until .data.claimCheck.state is neither pending nor checking, then push. If it ends as failed, the check did not run, and that does not hold the push back: the push goes through and is recorded as published without a check.

  • open_findings: stop. Checking again does not clear findings. A person must accept or fix them, so leave the output for them and pass on the requestId.

Do not retry a push unchanged after claim-check-blocked.

Report a problem with this page

On this page