Live run #692 got all the way to nocodb_upsert on a fresh
Substack CRM record and hit HTTPError 400 Bad Request on the
POST. The traceback only showed the URL and status, not the
NocoDB response body — the actual field-level reason for the
400 is in that body, and the synthetic test in
test_upsert_synthetic.py already calls out the
SingleSelect-options-not-set gap on the live table as the
likely culprit.
Wrap the POST and PATCH in 'if not resp.ok' to raise a
RuntimeError that includes the response body, table_id, and
record_keys (or record_id) so the next run's log can pinpoint
the exact NocoDB column that's rejecting the record.
Offline tests: 10/10 still pass.
Refs: INB-17
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Adds a workspace-level opencode.json at the repo root that overrides
the (varying) global config. It declares:
- the 'ollama' provider pointed at $OLLAMA_BASE_URL (the FRP tunnel)
- the four model entries the InboxOS prompts actually reference
- the five 'inboxos:*' commands inline (template: {file:...} so the
markdown bodies under .opencode/commands/*.md stay the source of
truth and continue to work via slash-commands in the TUI)
Verified end-to-end from inside the repo with the harness env scrubbed:
echo '{...test email JSON...}' | OLLAMA_BASE_URL=https://ollama-frp.cloudinit.dev/v1 \
opencode run --command inboxos:classify
=> {"modules": ["crm"]}
This is the correct shape for INB-20: the previous heartbeat's plan
to version-pin opencode-ai to 1.15.13 was the wrong remedy because
the root cause is config mismatch, not the CLI version. opencode
1.16.2 still wraps the underlying 4xx as UnknownError on the CLI
side (separate upstream bug), but with the workspace config in place
the model resolves and the call succeeds.
Also reverts the workflow-side pin: the install step is back to
'latest' and the strict version-mismatch gate is removed.
Co-Authored-By: Paperclip <noreply@paperclip.ing>