Output, JSON and exit codes

Synck is designed to be driven by people and by programs: shell scripts, scheduled jobs, editor integrations and AI agents. This page is the contract for programs.

Parse JSON, not the human-readable output. The plain-text output is meant for people, and its layout may change between releases. When a command’s output is shown in color on a terminal, the color is presentation only. Redirected output contains no color codes.

Commands that produce JSON

Always JSON. Every synck repository ... and synck item ... command prints one JSON document on success, with no flag needed.

JSON on request. These commands print JSON when you pass the global --json flag before the command name:

synck --json info          synck --json log         synck --json deleted
synck --json context       synck --json show REV    synck --json versions PATH
synck --json status        synck --json history P   synck --json version list PATH
synck --json diff [A B]    synck --json compare A B synck --json config ...
synck --json commit ...    synck --json revert ...  synck --json monitor ...
synck --json fsck          synck --json storage

Other commands, such as mv, restore, export and archive, refuse --json explicitly rather than printing something unexpected:

$ synck --json gc
{"error":{"kind":"INVALID","message":"--json is not supported for this command"},"schema_version":5}

The shape of results

Every JSON document is one object. The everyday commands include "schema_version": 5. Most repository commands include "schema_version": 1. The item commands, repository verify and fsck return their data object directly, as shown in Reading items and history. Beyond that, a result’s fields depend on the command:

$ synck --json info
{"author":"Alex Morgan","format_version":6,"head":{"commit_id":"sha256:21fe97c4…352a","repo_seq":15},"repo_id":"01a17498-6f04-7d82-8d5b-d91939706deb","root":"/tmp/b2","schema_version":5}
$ synck --json status
{"changes":[],"schema_version":5}
$ synck --json commit -m "Add the budget"
{"commit_id":"sha256:1d58ac30db937776c0915e6e40ad40a0c02a0f0805e8848af2e2602672c8481d","schema_version":5}

commit returns the new commit_id, or null when there was nothing to commit; commit --batch returns commit_ids in order and items_changed. revert returns the new commit_id. diff returns entries, each with old_path, new_path, a kind of PATCH, BINARY or TOO_LARGE, and the unified patch text for PATCH entries.

Do not assume a shared envelope. Read the fields each command returns. Change kinds in status, log and show are ADD, MODIFY, RENAME, MOVE, MOVE_RENAME and DELETE, with a separate content_changed flag.

Errors

Errors go to standard error. Without --json, an error is one line starting with synck:. With --json, it is a JSON document. That includes repository and item commands, which accept --json for exactly this purpose:

{"error":{"kind":"INVALID","message":"..."},"schema_version":5}

The message is for people. Branch on kind:

Kind Meaning
USAGE The command line was invalid
INVALID The request was understood but cannot be done as asked: a missing item, an existing destination, an unclean working tree
BUSY Another Synck process holds the repository lock. Retry later
INTEGRITY Stored data is not what its history says. See Checking integrity
ACCEPTED_NEEDS_RECOVERY The commit was accepted, but follow-up work is pending. Do not retry; run the next command or repository finalize
BATCH_COMMIT_INCOMPLETE Some commits of a batch were accepted. Their IDs are reported
MOVE_NEEDS_RECOVERY An mv was interrupted after acceptance and will be completed by the next command
PUBLISHED_NEEDS_DURABILITY An output was published, but the final flush to disk failed. Inspect it before assuming anything
FILE_FOLDER A file or folder rule was violated, such as a name collision
VCS The engine rejected the change, for example as stale
IO, SQLITE, CONFIG_JSON The file system, the database or the configuration file failed
MONITOR_UNAVAILABLE The background monitor could not be reached

Several kinds mean “something was recorded”. Treat ACCEPTED_NEEDS_RECOVERY, BATCH_COMMIT_INCOMPLETE, MOVE_NEEDS_RECOVERY and PUBLISHED_NEEDS_DURABILITY as partial successes, never as failures to retry blindly. See When an operation is interrupted.

Exit codes

Code Meaning
0 Success
1 The command failed
2 fsck or repository verify found an integrity problem, or the command line was invalid

Because 2 has two meanings, a script that checks integrity should look at the output as well as the code: an error kind of INTEGRITY from fsck or repository verify, as opposed to USAGE.

Tips for automation

  • Run one Synck command at a time per repository, and treat BUSY as “retry later”.
  • Before changing a repository’s files, read synck --json context and synck --json status, so you know what is already uncommitted.
  • Commit only the paths your program changed: synck commit -m "..." PATH ....
  • Never retry a write after an ACCEPTED_NEEDS_RECOVERY.
  • synck instructions prints a compact operating guide written for exactly this kind of use. Giving it to an AI agent before it works in a repository is a good idea.