Troubleshooting
What goes wrong most often, why, and how to fix it. Each problem has one line on why and one fix; open More for the rest.
Start with bb doctor. It checks your machine, and in a project the project and its Storyblok space, and gives the exact steps for each thing that’s missing:
npx -y @ef-global/backbase doctor
bb doctor
Doctor shows every check in a table, with the steps under each that fails or warns: they’re the steps below, word for word. A failure stops /backbase:new before it makes anything; a warning stops nothing. After a fix, run bb doctor again. Each check’s id links here, as #<id>.
On Windows
bb doctor and bb create find both .exe programs and .cmd shims on your PATH, including npm, npx, pnpm and Claude Code, and paths may contain spaces. If an older bb says npm isn't on PATH though npm --version works, or rejects a GitHub Packages token that works with npm, update bb and run doctor again. When a command times out, bb stops its child processes too.
node: Node is too old
Fails. Why: bb runs on Node 20 and up, and doctor says Node 18.19.0 is older than 20, with your version.
Fix: install Node 22 (LTS), then open a new terminal.
Doctor’s steps
- Install Node 22 (LTS) from https://nodejs.org, or with nvm:
nvm install 22 && nvm alias default 22 - Open a new terminal and check it:
node --version
git: git isn’t installed
Fails. Why: bb create clones and commits with git. Doctor says git isn't on PATH, or git is on PATH, but git --version fails.
Fix: install git, then open a new terminal.
Doctor’s steps
- Install git: on macOS run
xcode-select --install, otherwise see https://git-scm.com/downloads - Open a new terminal and check it:
git --version
bb-binary: another bb on your PATH
Warns. Why: the bb on your path is another program, often Babashka, or another version. It matters only when you type bb yourself: the plugin runs Backbase’s through npx.
Fix: Run Backbase’s bb through npx: npx -y @ef-global/backbase <command>
More
When there’s no bb on your path at all, it passes. When the bb there is Babashka, an unrelated Clojure tool with the same name, or another program that doesn’t print a version:
- Run Backbase’s bb through npx:
npx -y @ef-global/backbase <command> - Or add it to the project, so the plugin uses that one:
npm install --save-dev @ef-global/backbase - Or put Backbase’s bb first on PATH:
npm install -g @ef-global/backbase, then make sure npm’s global bin folder (npm prefix -g, then/bin) comes before the other bb’s folder.which -a bblists them in order
When it’s another version of Backbase’s bb:
- Install this version:
npm install -g @ef-global/backbase@<version> - Or run it through npx:
npx -y @ef-global/backbase <command>
github: not signed in to GitHub
Fails. Why: the plugin and the boilerplate both live in ef-global on GitHub. Doctor says gh isn't signed in to GitHub, gh isn't installed, and neither GH_TOKEN nor GITHUB_TOKEN is set, or gh auth status didn't answer in time.
Fix: gh auth login
Doctor’s steps
- Install the GitHub CLI if you haven’t: https://cli.github.com (on macOS:
brew install gh) - Sign in:
gh auth login - Check it:
gh auth status
When doctor says GitHub doesn't accept the token in GH_TOKEN, gh is using a token from your environment that doesn’t work. The same goes for GITHUB_TOKEN:
- Replace or unset GH_TOKEN, then sign in:
gh auth login - Check it:
gh auth status
github-ssh: SSH to GitHub fails
Warns. Why: bb create clones over HTTPS instead, through gh’s sign-in, so you can leave it.
Fix: Connect once and accept GitHub’s host key: ssh -T git@github.com
More
Doctor says ssh isn't on PATH when there’s no SSH at all: there’s nothing to fix then. When it says github.com isn't a known host on this machine yet:
- Connect once and accept GitHub’s host key:
ssh -T git@github.com
When GitHub doesn’t accept an SSH key from this machine, or SSH didn’t sign in or didn’t answer in time:
- Create a key if you have none:
ssh-keygen -t ed25519 -C <your email> - Add it to GitHub:
gh ssh-key add ~/.ssh/id_ed25519.pub - If ef-global uses single sign-on, choose Configure SSO next to the key on https://github.com/settings/keys and authorise ef-global
- Check it:
ssh -T git@github.com
packages-token: npm can’t read @ef-global
Fails. Why: Backpack and bb install from GitHub Packages with GH_PACKAGES_TOKEN, and it isn’t set, or GitHub Packages refuses it: wrong or expired (E401), without read:packages or single sign-on (E403), or its account may not be in ef-global (E404).
Fix: create a classic token with read:packages, and export it as GH_PACKAGES_TOKEN in your shell profile.
Doctor’s steps
- Create a personal access token (classic) with the read:packages scope: https://github.com/settings/tokens/new?scopes=read:packages&description=Backbase
- If ef-global uses single sign-on, choose Configure SSO next to the token and authorise ef-global
- Export it in your shell profile (~/.zshrc or ~/.bashrc):
export GH_PACKAGES_TOKEN=<your token> - Open a new terminal, start Claude Code from it and run
bb doctoragain. Never paste the token into a chat with an agent
When doctor says npm isn't on PATH:
- Install Node 22 (LTS) from https://nodejs.org: npm comes with it
- Open a new terminal and check it:
npm --version
When it says GitHub Packages didn't answer within 10 seconds:
- Check your network or VPN, then run
bb doctoragain
figma-mcp: Figma isn’t connected
Skips neutrally when unseen. Why: doctor can see a local Figma connector or plugin, but not a claude.ai connector, so it says Figma: checked when the frame is read, with the hint “Add a Figma connector in your agent’s settings and sign in.”
Fix: nothing until reading the frame fails. Then sign in to Figma in the agent you use.
More
A detected connector or plugin passes. A local MCP that needs authentication doesn’t warn: your claude.ai connector can still work. bb doctor --write leaves this check out.
If the frame read fails, check the Figma connector in the agent you are using and sign in there. For a local Claude Code MCP, run claude mcp login figma (use your server’s name), then start a new session. For a claude.ai connector, reconnect Figma in claude.ai.
storyblok-token: no Storyblok token
Warns. Why: doctor says STORYBLOK_OAUTH_TOKEN isn't set. Only a write to Storyblok needs it, so this can wait. In a project, a token in .env passes this check: Covered by the project's .env (STORYBLOK_OAUTH_TOKEN).
Fix: see Setting the Storyblok token.
Doctor’s steps
With the token set, bb create writes it to the new project’s .env.
- In Storyblok, open My account, then Personal access token, and create one
- Put it in your project’s .env as this line:
STORYBLOK_OAUTH_TOKEN=<your token> - Or export it in your shell profile (~/.zshrc or ~/.bashrc):
export STORYBLOK_OAUTH_TOKEN=<your token>, then open a new terminal. A shell export overrides the project’s .env - Run
bb doctoragain in the project. Never paste the token into a chat with an agent
page-browser: bb has no browser
Warns. Why: bb’s Chromium isn’t in its cache yet, so bb page measure and compare can’t open a page. Doctor says bb's Chromium <version> isn't in bb's browser cache, <folder>, so bb page measure and compare can't open a page.
Fix: Run bb page browser install: it downloads about 120 MB into <folder>, and changes neither the project nor Playwright’s shared cache
More
Only measuring and comparing a page need it. A project whose own Playwright has its Chromium passes: bb uses it first, and it’s the project’s to install. A project’s Playwright without its Chromium is passed over, and doctor says so. A Playwright on your PATH never counts.
- Run
bb page browser install: it downloads about 120 MB into<folder>, and changes neither the project nor Playwright’s shared cache - Run
bb doctoragain
Don’t add Playwright to the project for bb, and don’t run npx playwright install: in Playwright’s shared cache, an install deletes the browsers it thinks unused, which other projects use.
When doctor says bb's playwright-core is missing, bb’s own install is incomplete:
- Install bb again:
npm install -g @ef-global/backbase, or run it withnpx @ef-global/backbase - Run
bb doctoragain
When doctor says bb can’t tell, its playwright-core names a Chromium revision per platform, and only Playwright knows this machine’s:
- Run
bb page browser install: Playwright installs Chromium only when it isn’t there yet - Run
bb page measure: it says when Chromium won’t start
See bb’s browser.
The checks below look at the project you run bb doctor in, and its Storyblok space. Outside a project they skip, and say why. Where a step names a file, <project> is your project’s folder.
project-backpack: Backpack missing or too old
Fails. Why: doctor says @ef-global/backpack isn't installed in node_modules, or Backpack 3.9.0 is installed, and Backbase supports Backpack 4 only.
Fix: Install the project’s packages, in the project’s folder: npm ci
Doctor’s steps
- Install the project’s packages, in the project’s folder:
npm ci - If npm can’t read @ef-global packages, fix
packages-tokenfirst - Run
bb doctoragain
When Backpack is older than 4:
- Move the project to Backpack 4: set
@ef-global/backpackto^4in package.json, thennpm install - Run
bb doctoragain
project-chaperone: Chaperone isn’t set up
Fails. Why: Chaperone can’t run Backbase’s preset in this project, and doctor names what’s missing. Outside a Backpack project, it skips.
Fix: bb doctor --write
More
What doctor can find missing:
.chaperone.jsonis missing, doesn’t extend the Backbase preset, or lacks a supported version pin (minimum 0.12.0). An older Chaperone fails every schema onschema-name-matches-folder(why), and doctor says so.component-map.exceptions.jsonis missing. Without it, Chaperone reportsCannot check registration, which no baseline can record:chaperone baselineexits 2.package.jsondoesn’t have@ef-global/backbaseas a dev dependency.@ef-global/backbaseisn’t installed innode_modules, so Chaperone stops withpreset file not foundand checks nothing.- It’s installed without its CLI,
node_modules/@ef-global/backbase/dist/cli.js, so each of the preset’s three command rules says@ef-global/backbase isn't installed in this project: run npx @ef-global/backbase doctor --write.
bb doctor --write (or --fix) adds the preset and the pin to .chaperone.json, keeping existing rules, other extends and newer pins; creates component-map.exceptions.json as {} when there’s none, never overwriting one; pins @ef-global/backbase to the running bb in devDependencies, moving a pin out of dependencies; and installs it with the package manager the lockfile names (npm install --save-dev --save-exact @ef-global/backbase@<version>, or pnpm add, yarn add or bun add). The install reads GitHub Packages, so it needs GH_PACKAGES_TOKEN, runs before doctor’s other checks, and when it fails, doctor shows the package manager’s error. Invalid JSON in .chaperone.json is reported, never replaced. Run it again and it changes nothing. The path needs its leading ./:
{
"chaperoneVersion": "0.12.0",
"extends": ["./node_modules/@ef-global/backbase/chaperone/backbase.json"]
}A bb that isn’t a release, such as one built from a branch, can’t pin itself:
- This bb (
<version>) isn’t a release, so it can’t pin itself. Add@ef-global/backbasetodevDependenciesat the release you use - Then run
bb doctor --writeto set up.chaperone.jsonandcomponent-map.exceptions.json
When package.json asks for a range, a tag or a path, doctor doesn’t choose a version for you:
- Install what package.json asks for,
@ef-global/backbase@<range>:npm install, or the install of the package manager the lockfile names - Then run
bb doctor --writeto set up.chaperone.jsonandcomponent-map.exceptions.json, when either is missing
Warns when the installed bb isn’t the one you’re running:
package.jsonpins an older bb:bb doctor --writeraises the pin and installs it.- It pins a newer bb: doctor never lowers a pin.
npx @ef-global/backbasein the project runs the installed one. - It pins a release, and you’re running a prerelease, such as
0.19.0-next.0: doctor won’t raise a release pin to a prerelease. Pin it yourself, then runbb doctor --write. node_modulesdoesn’t hold the pinned version:bb doctor --writeinstalls it.- It asks for a range, a tag or a path: that’s the project’s choice. Pin the version you want, then run
bb doctor --write.
See the Chaperone preset for the rules. Chaperone 0.12.0 is pinned and tested against the stock boilerplate.
project-prettierignore: Prettier checks build output
Warns. Why: Chaperone runs prettier --check ., which reads only .prettierignore, so without .next, .turbo and node_modules there it lints Next’s build cache.
Fix: Add .next, .turbo and node_modules to .prettierignore (bb doctor --write does too).
More
bb doctor --write and --fix add the missing lines under # Backbase, keeping the file’s own lines, or create the file.
project-launch: preview can’t start the site
Warns. Why: .claude/launch.json has no configuration for the project’s dev server, so Claude’s preview pane can’t start the site.
Fix: bb doctor --write
More
bb reads the server from package.json’s dev script, with the package manager the lockfile names, on the port the script gives (-p 3000, -p3000, --port=3000, PORT=3000), or 3000 for a plain next dev, with an https url for --experimental-https. In the boilerplate that’s npm run dev at https://localhost:3000. It skips with no dev script, or a port only the environment knows (-p $PORT).
bb doctor --write and --fix add { "name": "dev", "runtimeExecutable": "npm", "runtimeArgs": ["run", "dev"], "port": 3000, "url": "https://localhost:3000" } to the file’s configurations, keeping every other one, or create the file. A configuration named dev, or on the same port, counts already. A file that isn’t a launch file, or isn’t JSON, is a warning that names it, and doctor doesn’t touch it: fix it, then run bb doctor --write again.
catalog: the saved catalog is stale
Warns. Why: .backbase/catalog.json was saved for another Backpack, or before a schema changed, such as Backpack is 4.12.0 now, and it was saved for 4.11.0. Commands that take --catalog refuse it.
Fix: Rebuild it, in the project’s folder: bb catalog --json --out .backbase/catalog.json --if-stale
More
- Rebuild it, in the project’s folder:
bb catalog --json --out .backbase/catalog.json --if-stale - Run
bb doctoragain
Doctor’s command adds --space-presets .backbase/space-presets.json when that file is there, and --space <id> when the catalog was saved with one. It gives the same fix when the file isn’t a catalog bb can read.
When it says .backbase/catalog.json wasn't compared with the project, such as with a storyblok.config that won’t load, bb can’t build the catalog either:
- Run bb catalog in the project’s folder, and fix what it says about the project’s files
- Run
bb doctoragain
The skills rebuild the catalog and the knowledge pack themselves before they use them, and tell you when they did.
project-slots: slot files not installed
Warns. Why: under --write, doctor installs the slot component compose leaves for a missing component, and something in the project stood in the way.
Fix: do what the warning names, then run bb doctor --write again.
More
It runs only with --write and --fix, after catalog. It writes src/components/BackbaseSlot/BackbaseSlotSB.tsx, backbase-slot.sb.ts, the map entry in component-list.ts and the slot’s places in backbase.placements.json, through the project’s Prettier, and leaves files that are there already. It warns when:
- a slot file differs from bb’s:
… differs from bb's slot component; kept the project's file. Check its export and schema name; - the project has more than one
component-list.ts, orbackbase-slotis already mapped to another component; - the files are written, but the project’s Prettier failed.
project-storyblok-token: sb-mig has no token
Fails. Why: STORYBLOK_OAUTH_TOKEN isn't in the environment or in the project's .env, so sb-mig can't reach Storyblok, or it’s in .env but empty. Doctor only looks for the name, never the value.
Fix: see Setting the Storyblok token.
Doctor’s steps
- In Storyblok, open My account, then Personal access token, and create one
- Put it in
<project>/.envas this line:STORYBLOK_OAUTH_TOKEN=<your token> - Or export it in your shell profile (~/.zshrc or ~/.bashrc):
export STORYBLOK_OAUTH_TOKEN=<your token>, then open a new terminal - Never paste the token into a chat with an agent: no agent needs to see it. Then run
bb doctoragain
Warns when your shell and the project’s .env set different tokens: STORYBLOK_OAUTH_TOKEN is set in your shell and in the project's .env, and they differ. The shell's overrides the project's .env: sb-mig uses the shell's, and so does bb doctor. Remove one. It compares them without showing either. bb doctor --write doesn’t count this warning: space-access checks the shell’s token.
- Keep the token in
<project>/.env, and removeSTORYBLOK_OAUTH_TOKENfrom your shell profile (~/.zshrc or ~/.bashrc), then open a new terminal - Or, if the shell’s token is the right one, remove the
STORYBLOK_OAUTH_TOKENline from<project>/.env - Never paste either token into a chat with an agent. Then run
bb doctoragain
project-env-ignored: git could commit .env
Fails. Why: git doesn't ignore .env, or tracks it already, so the token could be committed. Without a .env, or outside git, it passes.
Fix: Add this line to <project>/.gitignore: .env
Doctor’s steps
- Add this line to
<project>/.gitignore:.env - If git tracks .env already, stop tracking it and keep the file:
git rm --cached .env - If a commit with .env was ever pushed, create a new Storyblok token and delete the old one
space-id: no Storyblok space id
Fails. Why: doctor says The project has no Storyblok space id, or that a value isn’t one, such as .backbase/config.json space.id must be a Storyblok space id, not "12a".
Fix: Add it to <project>/.backbase/config.json as space.id: { "space": { "id": "<space id>" } }
Doctor’s steps
- Add it to
<project>/.backbase/config.jsonas space.id:{ "space": { "id": "<space id>" } } - Or set spaceId in storyblok.config
- Or pass it for one run:
bb doctor --space <space id> - Or set
STORYBLOK_SPACE_IDin your shell or the project’s.env; find the id in the space’s settings in Storyblok
--space and the config files come first, and the shell wins over .env. With --space, doctor reads neither config file.
space-access: Storyblok refuses the token
Fails. Why: doctor asks Storyblok for the space, read-only, and it didn’t answer with the space. It’s skipped until space-id and project-storyblok-token pass.
Fix: Check the token is the personal access token of a Storyblok account with access to this space
More
Doctor asks the Management API sb-mig uses: storyblokApiUrl in storyblok.config, then NEXT_PUBLIC_STORYBLOK_MANAGEMENT_API_URL in your shell or the project’s .env, then the EU API.
When Storyblok refuses the token (401 or 403): the token is wrong or has expired, or its account has no access to that space.
- Check the token is the personal access token of a Storyblok account with access to this space
- If it isn’t, or has expired: in Storyblok, open My account, then Personal access token, and create one
- Put the new one in the project’s .env as
STORYBLOK_OAUTH_TOKEN=<your token>, or export it in your shell profile. Never paste it into a chat with an agent
When Storyblok has no such space (404): the space id is wrong, or the space is in another region.
- Check the space id in the space’s settings in Storyblok
- If the space is in another region, set storyblokApiUrl in storyblok.config to that region’s Management API: EU
https://mapi.storyblok.com/v1, UShttps://api-us.storyblok.com/v1, CAhttps://api-ca.storyblok.com/v1, APhttps://api-ap.storyblok.com/v1, CNhttps://app.storyblokchina.cn/v1
When Storyblok doesn’t answer within 10 seconds, or can’t be reached:
- Check your network or VPN, then run
bb doctoragain - If the space is in another region, set storyblokApiUrl in storyblok.config to that region’s Management API, as above
When Storyblok answered with an error, such as 500:
- Storyblok may be busy or down: wait a minute, then run
bb doctoragain
When the Management API URL isn’t https, or isn’t a Storyblok Management API host, bb didn’t send the token: it sends it only over https to Storyblok’s own hosts (and to localhost or 127.0.0.1, for tests).
- Set storyblokApiUrl in storyblok.config to your region’s Management API: EU
https://mapi.storyblok.com/v1, UShttps://api-us.storyblok.com/v1, CAhttps://api-ca.storyblok.com/v1, APhttps://api-ap.storyblok.com/v1, CNhttps://app.storyblokchina.cn/v1
When Storyblok answered, but not with a space:
- Check that storyblokApiUrl in storyblok.config, or NEXT_PUBLIC_STORYBLOK_MANAGEMENT_API_URL, is a Storyblok Management API: EU
https://mapi.storyblok.com/v1, UShttps://api-us.storyblok.com/v1, CAhttps://api-ca.storyblok.com/v1, APhttps://api-ap.storyblok.com/v1, CNhttps://app.storyblokchina.cn/v1
When the token has spaces or line breaks in it, bb didn’t send it:
- Copy the token from Storyblok again, with nothing before or after it
- Put it on one line in the project’s .env as
STORYBLOK_OAUTH_TOKEN=<your token>, or export it in your shell profile. Never paste it into a chat with an agent
When storyblok.config can’t be loaded, bb can’t tell which API sb-mig uses: doctor evaluates it in the project, as bb catalog does.
- Fix storyblok.config so it loads, then run
bb doctoragain
project-translation-strategy: stories in locale folders
Warns for folder or an unsupported strategy; otherwise it passes. Why: with folder, the site asks for a locale path, so compose writes under the default locale’s root folder.
Fix: For a site without locale folders, set NEXT_PUBLIC_TRANSLATION_STRATEGY=none in the project’s .env
More
NEXT_PUBLIC_TRANSLATION_STRATEGY is read in Next’s order: shell, .env.local, then .env, defaulting to none. Doctor and compose share the reader. none and field use root stories. It’s advisory, under --write too.
For folder:
- Put stories and a settings story under each locale folder in Storyblok
- For a site without locale folders, set NEXT_PUBLIC_TRANSLATION_STRATEGY=none in the project’s .env
For an unsupported strategy, correct the source doctor names; a shell or .env.local value wins over .env. For .env:
- Set NEXT_PUBLIC_TRANSLATION_STRATEGY in the project’s .env to none, field or folder, then run bb doctor again
space-settings-story: no settings story
Warns. Why: the boilerplate needs a story with slug and content type settings, and it’s missing, the wrong type, or can’t be checked.
Fix: In Storyblok, create a story with slug settings and content type settings at the root (settings)
More
It’s advisory, under --write too, and doctor never creates or publishes a settings story. Folder locales come from languageMap.locales in src/lib/i18n/languageMap.mjs.
For none or field:
- In Storyblok, create a story with slug settings and content type settings at the root (settings)
For folder, create settings in each locale folder. For example, with locales en and de:
- In Storyblok, create a story with slug settings and content type settings in the en locale folder (en/settings)
- In Storyblok, create a story with slug settings and content type settings in the de locale folder (de/settings)
When a story at settings has another content type, doctor names it:
- In Storyblok, use content type settings for the story at settings
When doctor can’t read the locale map or the stories:
- Check the project’s translation strategy, locale map and Storyblok connection, then run bb doctor again
space-field-plugins: the space lacks a plugin
Warns. Why: a component uses a field plugin the space doesn’t have, so sb-mig would fail on it at Gate 2 with Storyblok’s 422. It never blocks a write: the rest of the sync, the theme included, still goes through.
Fix: Install <plugin> in the space (in Storyblok, through the plugin’s app or the organisation’s field plugins), then run bb doctor again
More
It warns only on positive evidence: the account’s or organisation’s list assigns the plugin to other spaces and not this one. For example: The space lacks field plugin description, so sb-mig would fail on sb-submit-button (field description, plugin description).
- Install
<plugin>in the space (in Storyblok, through the plugin’s app or the organisation’s field plugins), then run bb doctor again - Or leave the component out at Gate 2:
bb space plan --exclude <component>. Add your reason as--exclude "<component>=<your reason>", and the plan lists it. The agent offers it when this check, or a sync, flags the component
A plugin it couldn’t verify isn’t a finding: it isn’t listed, is listed without its spaces, or the token can’t read the lists. bb then never suggests leaving a component out.
When it can’t read the project’s catalog, it can’t tell which plugins the components use:
- Install the project’s dependencies (npm ci), then run bb doctor again
storyblok-mcp: Storyblok isn’t connected
Warns. Why: doctor finds no Storyblok plugin in Claude Code’s settings and no connected server in claude mcp list. A claude.ai connector shows in neither, so it only warns: check with /mcp.
Fix: In Claude Code, run /mcp and choose Storyblok to sign in
More
When there’s no Storyblok connection it can see, from Storyblok’s setup guide:
- Add Storyblok’s MCP server:
claude mcp add --transport http --scope user Storyblok https://mcp.storyblok.com/mcp(or--scope project, for this project only) - In Claude Code, run
/mcpand choose Storyblok to sign in - For Codex, Cursor and other clients, follow https://www.storyblok.com/docs/tooling/mcp-server/setup
When a Storyblok server is configured but not connected:
- In Claude Code, run
/mcpand choose Storyblok to sign in, with your server’s name if it isn’tStoryblok - Start a new Claude Code session, so it loads the connection
Setting the Storyblok token
When: project-storyblok-token fails, storyblok-token warns, or space-access says Storyblok refuses the token.
Why: sb-mig reads a Storyblok personal access token from STORYBLOK_OAUTH_TOKEN, in your shell or the project’s .env, and it isn’t in either, or doesn’t work.
Fix: put it in the project’s .env, the recommended place:
- In Storyblok, open My account, then Personal access token, and create one
- Put it in the project’s
.env, in the project’s folder, as this line:STORYBLOK_OAUTH_TOKEN=<your token>. Or export it in your shell profile (~/.zshrcor~/.bashrc):export STORYBLOK_OAUTH_TOKEN=<your token>, then open a new terminal - Run
bb doctoragain in the project
A shell export overrides .env: with both set, sb-mig uses the shell’s, and project-storyblok-token warns if they differ. Never paste the token into a chat with an agent: none needs it, and none will ask. bb doctor only says whether it’s there and works, and project-env-ignored checks git won’t commit .env.
bb create
bb create runs its steps in order, and stops at the first that fails with its message and fix. /backbase:new shows you both, and stops too.
The folder isn’t empty
Why: the folder holds something already, and bb never overwrites a file.
Fix: pick another folder name, or empty the folder, then run it again.
More
/backbase:new stops before it creates anything and asks about the folder. bb create stops at Check the folder with <folder> isn't empty. bb create makes a new folder, or fills an empty one, and never overwrites. For a half-made project from a run that failed, see bb create stopped halfway.
Stopped at Check the machine
Why: right after the folder check, it runs the machine checks it needs, node and git, the same as bb doctor’s. Nothing is written yet.
Fix: follow the check’s steps, such as git’s, then run bb create again.
More
It shows the check’s id and detail, such as git: git isn't on PATH., then Fix: and the steps. --json lists every check in data.checks, and one that warns in data.warnings, without stopping.
bb create can’t reach the boilerplate
Why: neither SSH nor HTTPS gets into GitHub from this shell, and bb never stops to ask for a password or a passphrase.
Fix: gh auth login, then gh auth setup-git, and run bb create again.
More
It stops at Resolve the ref with Couldn't reach ef-global/storyblok-nextjs-backpack-boilerplate, and a reason for each. SSH has no key GitHub accepts (or ssh-agent doesn’t hold it), and HTTPS has no credential helper with access to ef-global. Set up either:
-
HTTPS, the quickest:
gh auth login gh auth setup-git -
SSH: add your key to GitHub and to
ssh-agent, and check it withssh -T git@github.com.
--transport https or --transport ssh uses only that one. bb create doesn’t need a gh sign-in first: git may clone with another credential helper, such as the macOS keychain. Only when HTTPS fails too does it run doctor’s github check, and give its fix.
It cloned over HTTPS, not SSH
Why: bb create tries SSH first and falls back to HTTPS when SSH doesn’t sign in, never waiting on a prompt. Resolve the ref says master is 1a2b3c4, over https (ssh: …).
Fix: nothing: the project is the same. For SSH next time, follow github-ssh.
More
bb doctor warned about it as github-ssh. --transport ssh makes bb create use only SSH, and fail when it can’t.
bb create stopped halfway
Why: a step after the clone failed, such as Install, and the failed run left a half-made project, so running it again says the folder isn’t empty. With --json, data.leftBehind is true.
Fix: do what the error says, then delete the folder and run bb create again.
More
Install errors include GH_PACKAGES_TOKEN isn't set, packages-token: GitHub Packages doesn't accept the token in GH_PACKAGES_TOKEN and npm ci failed. bb checks the GitHub Packages token only right before the install, once the clone’s .npmrc needs it; when GitHub Packages doesn’t answer in time, it warns and installs anyway. For the token, see packages-token; the install’s output is in .backbase/install.log. /backbase:new never deletes the folder for you. When only First commit failed, you don’t need to start again: see git has no identity.
git has no identity
Why: git needs a name and an email for the first commit, and bb create never makes one up. First commit fails with git has no complete user identity (a name and an email, for the author and the committer).
Fix: set yours, then make the first commit as the error shows it.
More
Everything before the commit worked. Use the short SHA the error gives:
git config --global user.name "Your Name"
git config --global user.email "you@ef.com"
cd my-site && git add -A && git commit --no-verify --no-gpg-sign -m "Start from storyblok-nextjs-backpack-boilerplate@<short sha>"GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL work too. Then run /backbase:analyze <figma link> --project my-site to carry on.
The first commit isn’t signed
Why: bb create commits with --no-gpg-sign, because signing would ask for a passphrase an agent would wait on forever. Its step reads “unsigned first commit”.
Fix: sign it yourself, in the project: git commit --amend --no-edit -S
npm and Figma
npm returns 401 for @ef-global
Why: npm reaches GitHub Packages but can’t sign in: the token is missing, expired or lacks read:packages, or GH_PACKAGES_TOKEN isn’t set in the shell that runs npm.
Fix: check ~/.npmrc has both lines from step 4 of Getting started.
More
It fails with E401 or 401 Unauthorized, from npm install or npx -y @ef-global/backbase.
- Check that
~/.npmrchas both lines from step 4 of Getting started. - Make sure the token is a classic token with
read:packages, and that it hasn’t expired. If your organisation uses single sign-on, authorise the token foref-globalon GitHub. - If the project’s
.npmrcuses${GH_PACKAGES_TOKEN}, export it and check it’s there:echo "${GH_PACKAGES_TOKEN:+set}"printssetwhen it has a value. Restart Claude Code from that shell.
A 404 Not Found instead usually means the @ef-global:registry line is missing, so npm looks on the public registry.
Desktop app Figma sign-in fails
Why: the desktop app’s sign-in for remote MCP servers is less reliable than the terminal’s: the browser opens, but the sign-in never completes.
Fix: sign in from a terminal, claude mcp login figma, then start a new session.
The Figma MCP isn’t connected
Why: it was never added, was added for one project only, or isn’t signed in. Claude Code loads MCP servers only when a session starts.
Fix: claude mcp list, and add or sign in to figma if it isn’t there.
More
/backbase:analyze, or /backbase:new after it made the project, stops at the analyse flow’s first checks. Add it for your user, and sign in:
claude mcp add --transport http --scope user figma https://mcp.figma.com/mcp
claude mcp login figmaThen start a new session and run /backbase:analyze again. When /backbase:new already made the project, run /backbase:analyze <figma link> --project <folder>.
Very tall frames
Why: a tall frame has more layers than one Figma response can hold: reading stalls, a response is cut off, or the session runs out of room.
Fix: link a smaller frame, a group of sections rather than the whole page.
More
The agent is built for this: it takes the outline from a small script instead of get_metadata, which fails on very large frames, screenshots a tall frame part by part, and reads three parts a call, halving the batch when one overflows. You can also split the page into a few frames in Figma and analyse each in its own session.
bb isn’t found, or is Babashka
Why: bb doesn’t need to be installed globally, and a bb on your path may be Babashka, an unrelated Clojure tool. You see bb: command not found, or a babashka version.
Fix: run Backbase’s through npx: npx -y @ef-global/backbase --version
More
The plugin runs the project’s own bb from node_modules/.bin, or else npx -y @ef-global/backbase@<version>, pinned to its release. To have the agent use the project’s:
npm install --save-dev @ef-global/backbase
npx bb --versionYou don’t need to uninstall Babashka. If the agent runs plain bb and gets Babashka, tell it to use npx -y @ef-global/backbase.
The plan and the space
Not a Backpack project
Why: there’s no node_modules/@ef-global/backpack: the dependencies aren’t installed, Claude Code started in another folder, or the project doesn’t use Backpack 4.
Fix: npm install in the project (it needs the GitHub Packages setup).
More
Start Claude Code in the project’s root folder, or pass --project <dir>. To start without a project, run /backbase:new <figma link> <folder>: see Start from scratch.
A command says catalog-stale
Why: the catalog was saved at analyse time, and Backpack or a schema changed since. bb never uses a catalog for another Backpack.
Fix: run the command the message ends with, such as bb catalog --json --out .backbase/catalog.json --if-stale, then yours again.
More
It reads .backbase/catalog.json was saved for Backpack 4.11.0, and the project has 4.12.0, or was saved before these changed: and the schema files. Rebuild the knowledge pack too, with bb catalog --knowledge --out .backbase/knowledge.md --if-stale and the flags it was compiled with. The skills do both themselves.
Bloks missing from the component map
Why: component-list.ts has no entry for some bloks, so each renders nothing where the page hands it to the map. bb catalog lists a missing-map-entry for each.
Fix: register the ones that reach the map in component-list.ts, and list the rest in component-map.exceptions.json with a reason.
More
That’s often fine: some bloks never reach the map, because their parent renders them or reads them as data. List those at the project’s root:
{
"sb-link-card": "CardSB reads the link off `action` as data",
"sb-form-select-option": "FormSelectSB reads `options` as data"
}bb catalog then excuses them. The boilerplate’s npm run check:map reads the same file, and so does the Chaperone preset’s schema-is-registered rule, which needs it to exist: bb doctor --write creates it as {}.
Every component fails schema-name-matches-folder
Why: .chaperone.json pins a Chaperone older than 0.12.0, which ignores the preset’s case transform, so no folder ever matches. You see Put <kebab>.sb.ts in src/components/<PascalCase>/, and maybe warnings about unknown options such as transform.
Fix: npx @ef-global/backbase doctor --write
More
It raises chaperoneVersion to 0.12.0, keeping a newer pin, and Chaperone downloads that version on its next run. An older Chaperone also ignores the map exceptions and the command rules’ per-component results. bb doctor’s project-chaperone names the old pin.
A component failed at Gate 2
Why: sb-mig couldn’t write that component. The others were written, and so was the theme, which never waits on components.
Fix: let /backbase:sync plan again without it: bb space plan --exclude "<component>=<your reason>".
More
bb space sync fails with component-failed: sb-mig couldn't write component <name>; the other components were synced. Fix it and plan again, or leave it out: bb space plan --exclude <name>, with sb-mig’s words under it. When the space lacks a field plugin (Storyblok’s 422), it reads Storyblok says the space lacks field plugin <plugin>, which <name> needs: install it in the space, or leave <name> out, and .backbase/space-sync.json lists it under fieldPluginFailures.
/backbase:sync offers the ways round it, and does neither without your yes:
- For a missing field plugin, install it in the space, then plan and sync again. Doctor’s
space-field-pluginsnames it before a sync when it can tell - Or leave the component out with
--exclude, and take the new plan to Gate 2. A plan made again without it plans the component again, and fails on it again
component-not-synced means sb-mig’s report lacks a component the sync named, so it wasn’t written. sb-mig finds a component by its schema file’s name: check each has one .sb file named after it (not one in the project and another in node_modules), then plan again.
Gate 2 skipped the theme
Why: bb writes the theme only as planned, and someone changed a token or saved the Settings story since the plan, or the sync wrote a datasource the theme was planned from.
Fix: close Settings in Storyblok, run /backbase:sync again, and approve the new plan.
More
bb space sync fails with theme-plan-again: 1 theme write wasn't made, as the space changed since the plan. Run bb space plan --sections again and take the new plan to Gate 2., then each write it skipped. Or the sync went through, and the old theme came back once someone saved Settings: Storyblok has no conditional write, so a Settings tab opened before the sync holds the old theme, and saving it brings it back.
- Close the Settings story in Storyblok before the sync, and reopen it after
- Run
/backbase:syncagain, so it plans the theme again, and approve the new plan at Gate 2: it needs its own yes - bb saves the Settings story as a draft and never publishes it: publish it when you’re happy
The page
The page didn’t settle
Why: bb measures a page only once it has loaded and holds still, and something kept loading or moving for 20 seconds. You see page-not-settled, and what was still busy.
Fix: reload the page in your browser, then run the command again.
More
The error names it, such as Hero (9:1)'s height went from 480px to 612px, 2 images weren't decoded, the network wasn't idle: 1 request still loading (/api/prices) or the page reloaded while settling. The skills wait and try once more, then tell you. Then:
- A dev server compiling the page on first visit can take longer than 20 seconds: reload it, then run the command again.
- A slow page: give it longer with
--settle-timeout 60000. - A section that keeps moving, or an image that never loads, such as an autoplaying carousel whose slides differ in height: look at that section on the page.
- The page reloaded: the dev server reloaded it, often because a file changed. Run it again once it’s quiet.
- The network is never idle: something starts a request less than half a second after the last ended, such as analytics or a chat widget. Turn it off in development. A poll every few seconds is fine.
--allow-unsettled measures anyway, marked settled: false, and nothing is judged from it: use it to look, not to refine. See Waiting for the page to settle.
A section wasn’t reviewed
Why: the review captures a section only once it has settled in view, and never crops a half-loaded one. bb page review lists it as not-captured, with a reason.
Fix: run it again for that section: bb page review … --section <key>.
More
It didn't settle in view:, orit moved while it was captured: run it again with--section <key>, the key fromindex.json. A section that never holds still in view, such as a carousel whose slides differ in height, needs its motion turned off in development;--settle-timeout 60000helps one that’s just slow.None of its bloks … has an element with a box on the page: the page doesn’t render the story withdata-blok-uid. Render it throughbb story serve, or the preview route with--draft.No Figma shot for it: the read skill didn’t save<node id>.pnginshots/besidesections.json. Read the frame again, or pass--shots <dir>.The review ran out of its 180s (--review-timeout): review the rest with--section <key>, or give it longer with--review-timeout 300000.
A sticky bar shows only once
Why: that’s on purpose. The review captures a tall section a viewport at a time, so bb pins a bar that’s sticky inside the section where the flow puts it, rather than at the top of every slice.
Fix: nothing. Compare the bar with where the frame draws it.
More
A booking bar or a section’s own nav shows once, at the top of the section. While it captures, bb sets it position: relative, which moves nothing, and puts it back after. What’s fixed or sticky outside the section, such as the site’s header, is hidden. When Figma shows the bar stuck lower down, that’s a layout item for the review, not a capture problem.
Grid or flex collapses when shown
Why: a local wrapper calls Backpack’s getVisibilityClasses without originalDisplayProperty, so Show adds block and the root’s grid or flex is gone. Wrappers that bb component new 0.18 or earlier wrote do this.
Fix: bb check components --visibility, then let /backbase:component fix each wrapper it names.
More
Its stack, grid or row collapses into a block once its visibility is Show, as FanStack’s did in the ILS run: Backpack’s cn keeps the last display class. /backbase:component makes the change only after you say yes. To do it yourself, pass the display it names, such as originalDisplayProperty: 'grid', and name the classes in the file (grid md:grid lg:grid xl:grid xxl:grid) so Tailwind builds them. The preset’s wrapper-visibility-keeps-display rule runs the same check.
A dashed box, not a component
Why: it’s a backbase-slot, reserving a planned Wrap or Create. That’s expected in dev and drafts, and it renders nothing in published production content.
Fix: run /backbase:component to build it.
More
bb story slots --json shows its name, Figma node and kind. Refine skips its geometry. If the slot files are missing, run bb doctor --write and review its installation check.