Skip to content

BRANCH_ID: default everywhere, numeric only for branched storage - #97

Draft
claude[bot] wants to merge 4 commits into
mainfrom
fix/branch-id-wording-platform-vs-local
Draft

BRANCH_ID: default everywhere, numeric only for branched storage#97
claude[bot] wants to merge 4 commits into
mainfrom
fix/branch-id-wording-platform-vs-local

Conversation

@claude

@claude claude Bot commented Aug 4, 2026

Copy link
Copy Markdown

Requested by David Esner · Slack thread

End state

BRANCH_ID is optional everywhere, and the templates now behave that way. A user running any template locally does not have to set it — the effective value is default, which resolves to the production branch. The advice is identical on the platform and locally, which was the point of the change: nothing to look up, and no value that can drift between a developer's machine and the deployed app.

A numeric BRANCH_ID is the documented exception, needed only when the app has to read a development branch's tables (branched storage).

Why the framing flipped mid-PR

The first two commits on this branch were built on the premise that the Query Service rejects the string "default" with a parse error, so local dev had to pass a numeric branch ID. Review from the domain owner: that is not true — the Query Service accepts default.

With the premise gone, the two-context split that the earlier commits worked so hard to draw (platform injects the var, local dev must supply it) collapses. The two contexts no longer differ in any way the reader has to act on, so the subsection is now a single unified explanation instead of two mirrored cases.

Before this PR After the first two commits Now
Local dev "Defaults to default. Almost always leave it that way." — then, eleven lines down, "needs a numeric ID" Always set it, to the main branch's numeric ID Don't set it; falls back to default
Deployed Leave it out of the app config Leave it out of the app config Leave it out of the app config
Dev-branch tables Set the branch's numeric ID Set the branch's numeric ID Set the branch's numeric ID

Retained from the old text: data apps only ever run in the production branch and the var controls which branch's tables are read; use mcp__keboola__get_project_info rather than hand-rolling GET /v2/storage/dev-branches; the branch_id / is_development_branch fields; the Development Branches UI lookup. The is_development_branch check now reads the other way round — it tells you whether the branch_id you got back is the development branch you actually want, instead of gating against accidentally pasting a dev-branch ID.

Documentation

plugins/dataapp-developer/skills/dataapp-development/references/

  • storage-access.md §BRANCH_ID — rewritten. One unified explanation (normally unset, effective value default, same in both contexts) plus one exception (numeric ID for branched storage) with both lookup paths.
  • storage-access.mdBRANCH_ID marked optional in both required-env-var lists (§Direct RO workspace queries, §Alternative: Storage API workspace-query endpoint). The Storage API line no longer says the API "happens to tolerate" default with "no reason to rely on that" — default is simply fine there too.
  • storage-access.md — the SDK call-shape examples and the Storage Access wrapper (storage.py / storage.ts) now default to default (os.environ.get("BRANCH_ID", "default"), process.env.BRANCH_ID || 'default') instead of requiring the var, matching the Storage-API endpoint snippets that already did. The # numeric, not "default" comments are gone.
  • storage-access.md — dropped branch_id from the values the agent pre-fills into .env.local; there is nothing to fill in.
  • troubleshooting.md — the missing-env-var entry is no longer keyed on KeyError: 'BRANCH_ID' (nothing in the docs raises that any more) and now states outright that BRANCH_ID is not one of the variables to add.
  • python-js-apps.mdBRANCH_ID removed from the env vars to mirror locally.

Templates — actual behaviour change

plugins/dataapp-developer/skills/dataapp-development/templates/

  • streamlit/utils/data_loader.py — was: st.error("Missing BRANCH_ID. The Query Service requires a numeric branch ID — the string 'default' is rejected…") and an empty DataFrame. Now: branch_id = _get("BRANCH_ID") or "default". The WORKSPACE_ID check is untouched.
  • streamlit/.streamlit/secrets.toml.exampleBRANCH_ID = "510379" # numeric — Query Service rejects the string "default" moved into the commented optional block with a corrected comment. Three required keys, not four.
  • nodejs-app/api/keboola-client.jsresolveKeboolaEnv() returns branch: branch.value || 'default'; runQuery() no longer pushes BRANCH_ID onto missing. The pick('KBC_BRANCH_ID', 'BRANCH_ID') alias behaviour is deliberately untouched.

python-app/, python-node-app/ and duckdb-cache/ never referenced BRANCH_ID, so there was nothing to change. All three template README.mds already listed only KBC_URL, KBC_TOKEN, WORKSPACE_ID, so they were already consistent with BRANCH_ID being optional.

Deliberately left alone

  • docs/superpowers/plans/2026-05-13-dataapp-development.md — historical planning document. Its code samples already use _get("BRANCH_ID", "default") and pick('KBC_BRANCH_ID', 'BRANCH_ID'), so they happen to agree with the new guidance anyway.
  • The KBC_BRANCH_ID vs BRANCH_ID alias question, and adding .env.example files to templates that don't ship one — both flagged separately, neither approved here.
  • references/glossary.md's "Development Branches (find numeric branch ID)" UI pointer — still correct, that's the exception path.

Where the false claim came from

74c2020 (15 May) introduced it, in that commit message: "The Query Service rejects the string "default" for BRANCH_ID with a parse error." It landed with no repro, no captured error text, and no test. 76ee160 later the same day propagated it into the templates while migrating them off the legacy Storage API workspace endpoint; the failure that session actually recorded was 404 workspace.workspaceNotFound from the legacy endpoint, which is a different problem. The commit immediately before, 5152542, had said "leave it at default" — which is what this PR restores.

No version bumps or README changes

CLAUDE.md's four bookkeeping steps are scoped to adding commands, agents, or skills. This edits prose and template internals in an existing skill: no new skill surface, no frontmatter change, no file list change. Happy to add a patch bump if the convention is that docs/template edits ship one.

Verification

  • Tier 0 static lint, from evals/: uv run --group dev pytest -q329 passed, 32 skipped.
  • node --check templates/nodejs-app/api/keboola-client.js → clean.
  • python -m py_compile templates/streamlit/utils/data_loader.py → clean.
  • tomllib.load on templates/streamlit/.streamlit/secrets.toml.example → parses.
  • Tier 1 activation evals not run (need ANTHROPIC_API_KEY); none of this touches skill routing.

claude added 3 commits August 4, 2026 10:48
The BRANCH_ID subsection in the data-app development skill opened with
"Defaults to default (production). Almost always leave it that way.",
then eleven lines later told the reader local dev needs a numeric ID.
It also conflated two contexts: the platform injects BRANCH_ID on
deploy, whereas local dev has to supply it.

- Restructure the subsection into two clearly labelled cases: local dev
  (must be set, must be numeric — the normal path, since the templates
  use the Query Service, which rejects the string "default"), and
  deployed on the platform (leave it out of the app config; unset means
  the default/production branch).
- Drop the "or set it to default" advice — setting the literal string
  is not advisable; omit the variable instead.
- Keep the dev-branch-tables case, with the UI lookup, as the single
  reason to set it explicitly in either context.
- Reword the Storage API workspace-query env-var line so it no longer
  reads as a recommendation to pass "default"; the API tolerating the
  string is stated as a fact, not a suggestion.

No behaviour or code changes — reference prose only.
Review feedback: the previous version ended with "The one case for
setting it explicitly, in either context", presenting the
development-branch case as a single exception shared by both contexts.
That is wrong for local dev — locally you ALWAYS set BRANCH_ID. The
question there is never whether to set it but which numeric ID to use,
and in most cases that should be the main (production) branch's ID.

- Drop the "in either context" block; scope the dev-branch case once per
  context instead.
- Local dev: state that you always set it, and that the normal value is
  the main/production branch's numeric ID — which is what
  get_project_info returns as branch_id when is_development_branch is
  false. Reading a development branch's tables is now a sub-point of the
  local case, not a shared exception.
- Deployed on the platform: keep "leave it out of the app config", and
  note that there the dev-branch case genuinely is the one reason to set
  it explicitly.

All existing facts kept: apps only run in the production branch, the
Query Service rejects the string "default", use get_project_info rather
than hand-rolling GET /v2/storage/dev-branches, the
is_development_branch == false gating and its warning, and the
Development Branches UI lookup.

No behaviour or code changes — reference prose only.
…ment

Review correction from the domain owner: the Query Service does accept the
string "default" as a branch identifier. The premise the previous two commits
were built on ("QS rejects `default` with a parse error", so local dev must
pass a numeric ID) is false, so the advice collapses into one rule that holds
both on the platform and locally: don't set BRANCH_ID at all.

References:
- storage-access.md §BRANCH_ID: replace the two mirrored "local dev" /
  "deployed on the platform" cases with a single unified explanation —
  normally unset, effective value "default" (production branch), same in both
  contexts. A numeric ID is now the documented exception, needed only when the
  app reads a development branch's tables (branched storage). The
  get_project_info branch_id / is_development_branch lookup is kept but scoped
  to that exception (is_development_branch now tells you whether the returned
  branch_id is the dev branch you want), along with the "don't hand-roll
  GET /v2/storage/dev-branches" guidance and the Development Branches UI path.
- storage-access.md: BRANCH_ID marked optional in both env-var lists; the
  Storage API workspace-query line no longer warns against relying on
  "default"; SDK call-shape and Storage Access wrapper examples default to
  "default" instead of requiring the var, matching the endpoint examples that
  already did.
- storage-access.md: drop branch_id from the values the agent pre-fills into
  .env.local — there is nothing to fill in.
- troubleshooting.md: the missing-env-var entry is no longer keyed on
  KeyError: 'BRANCH_ID' (the examples no longer raise that), and states
  explicitly that BRANCH_ID is not one of the variables to add.
- python-js-apps.md: drop BRANCH_ID from the env vars to mirror locally.

Templates — behaviour change, a user no longer has to supply BRANCH_ID:
- streamlit/utils/data_loader.py: fall back to "default" instead of rendering
  an st.error and returning an empty DataFrame.
- streamlit/.streamlit/secrets.toml.example: BRANCH_ID moved to the commented
  optional block with a corrected comment; three required keys, not four.
- nodejs-app/api/keboola-client.js: resolveKeboolaEnv() defaults branch to
  'default'; runQuery() no longer reports BRANCH_ID as a missing env var.
  KBC_BRANCH_ID alias behaviour left untouched.

Tier 0 evals pass (329 passed, 32 skipped). node --check and py_compile clean
on the edited template files.
@claude claude Bot changed the title Clarify BRANCH_ID: platform config vs local dev BRANCH_ID: default everywhere, numeric only for branched storage Aug 6, 2026
…-platform-vs-local

# Conflicts:
#	plugins/dataapp-developer/skills/dataapp-development/references/storage-access.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant