BRANCH_ID: default everywhere, numeric only for branched storage - #97
Draft
claude[bot] wants to merge 4 commits into
Draft
BRANCH_ID: default everywhere, numeric only for branched storage#97claude[bot] wants to merge 4 commits into
default everywhere, numeric only for branched storage#97claude[bot] wants to merge 4 commits into
Conversation
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.
default everywhere, numeric only for branched storage
…-platform-vs-local # Conflicts: # plugins/dataapp-developer/skills/dataapp-development/references/storage-access.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by David Esner · Slack thread
End state
BRANCH_IDis optional everywhere, and the templates now behave that way. A user running any template locally does not have to set it — the effective value isdefault, 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_IDis 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 acceptsdefault.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.
default. Almost always leave it that way." — then, eleven lines down, "needs a numeric ID"defaultRetained 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_inforather than hand-rollingGET /v2/storage/dev-branches; thebranch_id/is_development_branchfields; the Development Branches UI lookup. Theis_development_branchcheck now reads the other way round — it tells you whether thebranch_idyou 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 valuedefault, same in both contexts) plus one exception (numeric ID for branched storage) with both lookup paths.storage-access.md—BRANCH_IDmarked 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"defaultwith "no reason to rely on that" —defaultis simply fine there too.storage-access.md— the SDK call-shape examples and the Storage Access wrapper (storage.py/storage.ts) now default todefault(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— droppedbranch_idfrom 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 onKeyError: 'BRANCH_ID'(nothing in the docs raises that any more) and now states outright thatBRANCH_IDis not one of the variables to add.python-js-apps.md—BRANCH_IDremoved 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". TheWORKSPACE_IDcheck is untouched.streamlit/.streamlit/secrets.toml.example—BRANCH_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.js—resolveKeboolaEnv()returnsbranch: branch.value || 'default';runQuery()no longer pushesBRANCH_IDontomissing. Thepick('KBC_BRANCH_ID', 'BRANCH_ID')alias behaviour is deliberately untouched.python-app/,python-node-app/andduckdb-cache/never referencedBRANCH_ID, so there was nothing to change. All three templateREADME.mds already listed onlyKBC_URL,KBC_TOKEN,WORKSPACE_ID, so they were already consistent withBRANCH_IDbeing 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")andpick('KBC_BRANCH_ID', 'BRANCH_ID'), so they happen to agree with the new guidance anyway.KBC_BRANCH_IDvsBRANCH_IDalias question, and adding.env.examplefiles 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"forBRANCH_IDwith a parse error." It landed with no repro, no captured error text, and no test.76ee160later the same day propagated it into the templates while migrating them off the legacy Storage API workspace endpoint; the failure that session actually recorded was404 workspace.workspaceNotFoundfrom the legacy endpoint, which is a different problem. The commit immediately before,5152542, had said "leave it atdefault" — 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
evals/:uv run --group dev pytest -q→ 329 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.loadontemplates/streamlit/.streamlit/secrets.toml.example→ parses.ANTHROPIC_API_KEY); none of this touches skill routing.