Summary
When a kbagent sync working tree has drifted from production (e.g. production was edited directly by someone else), there is no reliable, documented way to make the local tree match current production again. sync pull silently skips the affected configs, sync pull --force preserves them instead of overwriting, and the only workaround we found was hand-editing .keboola/manifest.json. On top of that, sync diff / sync status reported "in sync" for a project that actually differs from production — which makes them untrustworthy for auditing local-vs-production state.
Environment
kbagent v0.59.0 (auto-update to v0.65.1 fails silently: Auto-update failed; continuing with current version)
- macOS, zsh
- Multi-project, config-only sync trees (
sync pull --all-projects --no-jobs --no-storage), one .keboola/manifest.json per project. Files committed to git once at repo init; production is edited directly by several people.
Observed behavior
1. sync pull skips configs as "locally modified" and never fetches the current remote version
The local files were not edited by us (committed once at init), yet pull refuses to update them:
Success: Pulled 1 configurations (1 rows) into main/
Skipped (17) -- locally modified:
! keboola.snowflake-transformation/...
...
These configs genuinely differ from production — sync diff reports e.g.:
~ MODIFIED keboola.snowflake-transformation/.../<name>
input.tables list length changed: 44 -> 41
…but pull will not bring the remote version down.
2. sync pull --force does NOT overwrite them, and aborts on any conflict
Per its own help, --force preserves "locally-modified configs whose remote is unchanged", so a drifted tree stays drifted. And a single merge conflict aborts the entire pull, blocking refetch of every other config too:
Merge conflict: 2 config(s) changed BOTH locally and on the remote since the last pull:
! ...
Error: ... `sync pull --force` refuses to overwrite them ... Resolve each conflict first ...
There is no --theirs / --ours / "discard local" option to resolve this.
3. Pull is manifest-driven, not file-presence-driven
Deleting/moving the local files for a config does not make pull refetch it. Moving an entire project's main/ aside and re-pulling fetched only the configs whose remote hash had changed, and left everything else missing — because the manifest still considered them up to date.
4. The only way to force a clean full pull was manual manifest surgery
We had to back up .keboola/manifest.json, empty its configurations array, and pull again. Only then did the full project download from current production, and sync push --dry-run finally reported "No changes to push". Hand-editing the manifest should not be required to reconcile a drifted tree.
5. sync diff / sync status report "in sync" when the trees actually differ
A project whose flows are disabled in production (but enabled in the local repo) was reported as:
No differences found. Local and remote are in sync.
A writer that was renamed in production was also absent from the --all-projects summary counts. This means a project flagged "in sync" / "OK" cannot be trusted to actually match production — which defeats the purpose of using these commands to audit drift before a push.
Expected behavior
- A documented, supported way to discard local changes and make a project (or a single config) match current production, e.g.
sync pull --force --theirs or a sync reset, without hand-editing the manifest.
--force should be able to proceed past conflicts with an explicit resolution strategy instead of aborting the whole pull.
sync diff / sync status should reliably surface all real differences — including config-row additions/deletions, renames, and task enabled/disabled state — so "in sync" can be trusted.
Impact
We maintain production Keboola configs across ~20 projects via kbagent sync. Because sync diff/status can wrongly report "in sync", we can't trust an audit of which projects drifted; and reconciling a drifted project requires manual manifest edits, which is risky on production repositories.
Summary
When a
kbagent syncworking tree has drifted from production (e.g. production was edited directly by someone else), there is no reliable, documented way to make the local tree match current production again.sync pullsilently skips the affected configs,sync pull --forcepreserves them instead of overwriting, and the only workaround we found was hand-editing.keboola/manifest.json. On top of that,sync diff/sync statusreported "in sync" for a project that actually differs from production — which makes them untrustworthy for auditing local-vs-production state.Environment
kbagent v0.59.0(auto-update tov0.65.1fails silently:Auto-update failed; continuing with current version)sync pull --all-projects --no-jobs --no-storage), one.keboola/manifest.jsonper project. Files committed to git once at repo init; production is edited directly by several people.Observed behavior
1.
sync pullskips configs as "locally modified" and never fetches the current remote versionThe local files were not edited by us (committed once at init), yet pull refuses to update them:
These configs genuinely differ from production —
sync diffreports e.g.:…but
pullwill not bring the remote version down.2.
sync pull --forcedoes NOT overwrite them, and aborts on any conflictPer its own help,
--forcepreserves "locally-modified configs whose remote is unchanged", so a drifted tree stays drifted. And a single merge conflict aborts the entire pull, blocking refetch of every other config too:There is no
--theirs/--ours/ "discard local" option to resolve this.3. Pull is manifest-driven, not file-presence-driven
Deleting/moving the local files for a config does not make pull refetch it. Moving an entire project's
main/aside and re-pulling fetched only the configs whose remote hash had changed, and left everything else missing — because the manifest still considered them up to date.4. The only way to force a clean full pull was manual manifest surgery
We had to back up
.keboola/manifest.json, empty itsconfigurationsarray, and pull again. Only then did the full project download from current production, andsync push --dry-runfinally reported "No changes to push". Hand-editing the manifest should not be required to reconcile a drifted tree.5.
sync diff/sync statusreport "in sync" when the trees actually differA project whose flows are disabled in production (but enabled in the local repo) was reported as:
A writer that was renamed in production was also absent from the
--all-projectssummary counts. This means a project flagged "in sync" / "OK" cannot be trusted to actually match production — which defeats the purpose of using these commands to audit drift before a push.Expected behavior
sync pull --force --theirsor async reset, without hand-editing the manifest.--forceshould be able to proceed past conflicts with an explicit resolution strategy instead of aborting the whole pull.sync diff/sync statusshould reliably surface all real differences — including config-row additions/deletions, renames, and task enabled/disabled state — so "in sync" can be trusted.Impact
We maintain production Keboola configs across ~20 projects via
kbagent sync. Becausesync diff/statuscan wrongly report "in sync", we can't trust an audit of which projects drifted; and reconciling a drifted project requires manual manifest edits, which is risky on production repositories.