40 Replies
That’s actually a ZMK limitation, not something specific to Studio.
By default, ZMK reserves space for up to 6 layers in memory. If you need more, you can raise that limit by changing the config in your firmware repo before compiling your own firmware. You’ll want to add this line to your
Once you’ve done that, ZMK Studio will let you use the new maximum number of layers.
If you just stick with the precompiled firmware from our docs, you’ll be capped at 6. To go beyond that, you’ll need to build your own firmware from the ZMK config repos (Corne) or Lily58 wireless firmware guide, and then edit the keymap as needed.
Want me to walk you through exactly where to put that config line in your repo?
By default, ZMK reserves space for up to 6 layers in memory. If you need more, you can raise that limit by changing the config in your firmware repo before compiling your own firmware. You’ll want to add this line to your
.conf
file in your ZMK config repo:
(or whatever higher number of layers you want). Then rebuild your firmware through GitHub Actions and flash it to your nice!nanos.Once you’ve done that, ZMK Studio will let you use the new maximum number of layers.
If you just stick with the precompiled firmware from our docs, you’ll be capped at 6. To go beyond that, you’ll need to build your own firmware from the ZMK config repos (Corne) or Lily58 wireless firmware guide, and then edit the keymap as needed.
Want me to walk you through exactly where to put that config line in your repo?
Firmware | Typeractive.xyz Documentation
If you're not familiar, ZMK is a wireless-focused firmware, and it powers our Corne Wireless.
yes and please assume i have little knowledge in this
yes and please assume i have little knowledge in this
Got it — let’s go through this step by step as simply as possible 🙂
1. Make your own firmware repo - Go to our firmware guide for your board:
- Corne firmware guide
- Lily58 firmware guide
- Pick the correct repo (with or without nice!view) and click “Use this template” in the top-right corner. This makes a copy into your own GitHub account. 2. Find the right file - In your new repo, go to the
- You’ll see a file named something like
- Add this line at the bottom:
You can change “12” to however many layers you want. 4. Save your change - Scroll down, type a short message like “increase layer limit”, and click Commit changes. 5. Wait for GitHub to build it - Go to the Actions tab of your repo.
- After a few minutes, you’ll see a green check ✔️. Click the most recent run, then scroll down to Artifacts and download the
- Put each half into bootloader mode (double tap reset) and drag the matching
- After flashing, your keyboard will reboot with the new max layer count. --- After this, ZMK Studio will let you add up to 12 layers (or however many you set). 🎉
Do you want me to outline exactly how to enter the bootloader and flash step-by-step, too?
1. Make your own firmware repo - Go to our firmware guide for your board:
- Corne firmware guide
- Lily58 firmware guide
- Pick the correct repo (with or without nice!view) and click “Use this template” in the top-right corner. This makes a copy into your own GitHub account. 2. Find the right file - In your new repo, go to the
config
folder.- You’ll see a file named something like
corne.conf
or lily58.conf
. That’s where your keyboard’s configuration lives.
3. Add the new layer limit
- Edit the .conf
file (GitHub lets you click the pencil ✏️ to edit).- Add this line at the bottom:
You can change “12” to however many layers you want. 4. Save your change - Scroll down, type a short message like “increase layer limit”, and click Commit changes. 5. Wait for GitHub to build it - Go to the Actions tab of your repo.
- After a few minutes, you’ll see a green check ✔️. Click the most recent run, then scroll down to Artifacts and download the
firmware.zip
.
6. Flash your keyboard
- Unzip the file. You’ll find .uf2
files for the left and right halves.- Put each half into bootloader mode (double tap reset) and drag the matching
.uf2
file onto the NICENANO
drive.- After flashing, your keyboard will reboot with the new max layer count. --- After this, ZMK Studio will let you add up to 12 layers (or however many you set). 🎉
Do you want me to outline exactly how to enter the bootloader and flash step-by-step, too?
Firmware | Typeractive.xyz Documentation
If you're not familiar, ZMK is a wireless-focused firmware, and it powers our Corne Wireless.
Firmware | Typeractive.xyz Documentation
If you're not familiar, ZMK is a wireless-focused firmware, and it powers our Lily58 Wireless.
any reason i should use less than 12 layers? Why not 128 or something.
any reason i should use less than 12 layers? Why not 128 or something.
Great question 👍
The short answer: you’re limited by memory on the nice!nano, and ZMK has to store your entire keymap for every layer in its flash/RAM.
- Each extra layer adds more data that ZMK needs to keep track of.
- The nice!nano runs on the nRF52840, which has 256KB RAM / 1MB flash. That sounds like a lot, but ZMK itself, BLE (Bluetooth), bonds, and other features already take up a good chunk.
- If you set something extreme like 128 layers, it would massively bloat memory usage and either:
- Fail to compile, or
- Compile but crash at runtime (keyboard not booting / random behavior).
For most people:
- 6–12 layers is the sweet spot — plenty of room for standard keymap + layers for symbols, numbers, media, mouse keys, macros, etc.
- Beyond ~20 layers, you’ll almost never need that many, and it just adds risk of memory issues.
So setting it to 12 (or maybe 15 if you’re adventurous) gives you flexibility but keeps your firmware safe and stable.
👉 If you later really need more, you can increase in small steps, rebuild, and test.
Would you like me to suggest a typical smart way to organize layers so you rarely need more than ~10?
The short answer: you’re limited by memory on the nice!nano, and ZMK has to store your entire keymap for every layer in its flash/RAM.
- Each extra layer adds more data that ZMK needs to keep track of.
- The nice!nano runs on the nRF52840, which has 256KB RAM / 1MB flash. That sounds like a lot, but ZMK itself, BLE (Bluetooth), bonds, and other features already take up a good chunk.
- If you set something extreme like 128 layers, it would massively bloat memory usage and either:
- Fail to compile, or
- Compile but crash at runtime (keyboard not booting / random behavior).
For most people:
- 6–12 layers is the sweet spot — plenty of room for standard keymap + layers for symbols, numbers, media, mouse keys, macros, etc.
- Beyond ~20 layers, you’ll almost never need that many, and it just adds risk of memory issues.
So setting it to 12 (or maybe 15 if you’re adventurous) gives you flexibility but keeps your firmware safe and stable.
👉 If you later really need more, you can increase in small steps, rebuild, and test.
Would you like me to suggest a typical smart way to organize layers so you rarely need more than ~10?
8 vs 12? is the difference marginal?
Yep — the difference between 8 and 12 layers is basically marginal in terms of memory use 👍
- Each layer only adds a few hundred bytes, depending on your keymap size.
- Going from 8 → 12 layers is still totally safe — nowhere near the nRF52840’s memory limits.
- You really only start worrying once you go much higher (20+), or if you’re also enabling extra ZMK features (like advanced RGB, custom sensors, etc.).
So the real question is less about performance, and more about whether you need the extra layers:
- 8 layers is already more than most users ever use. (Base, Shifted symbols, Numbers, Nav/Mouse, Media, Bluetooth controls, maybe Macros…)
- 12 layers just gives some “future room” so you don’t rebuild later if you decide to experiment with crazy layouts.
👉 If you’re just starting out, I’d set it to 12. No downside, and you won’t hit the wall unexpectedly.
Do you want me to sketch a practical “layer plan” showing how most people fill up 6–8 layers, so you get an idea of what’s really needed?
- Each layer only adds a few hundred bytes, depending on your keymap size.
- Going from 8 → 12 layers is still totally safe — nowhere near the nRF52840’s memory limits.
- You really only start worrying once you go much higher (20+), or if you’re also enabling extra ZMK features (like advanced RGB, custom sensors, etc.).
So the real question is less about performance, and more about whether you need the extra layers:
- 8 layers is already more than most users ever use. (Base, Shifted symbols, Numbers, Nav/Mouse, Media, Bluetooth controls, maybe Macros…)
- 12 layers just gives some “future room” so you don’t rebuild later if you decide to experiment with crazy layouts.
👉 If you’re just starting out, I’d set it to 12. No downside, and you won’t hit the wall unexpectedly.
Do you want me to sketch a practical “layer plan” showing how most people fill up 6–8 layers, so you get an idea of what’s really needed?
i actually don't really like using ZMK studio. How else can I configure my board?
i actually don't really like using ZMK studio. How else can I configure my board?
i actually don't really like using ZMK studio. How else can I configure my board?
Totally fair — Studio is just one option 🙂. The “normal” way to configure your board is by editing the keymap file directly in your ZMK config repo and then rebuilding firmware.
Here’s how it works:
1. Open your config repo The repo you set up for firmware (like
-
This is your layout file. It’s just text that defines the layers and what keys go where. Example of a simplified layer section: -
- You can also use things like
- GitHub Actions will automatically rebuild your firmware.
- Download the new
4. Flash your board Double-tap reset, copy new
while editing the keymap repo = full control, but needs reflashing.
👉 If you’re comfortable tinkering, the repo method is actually more powerful — you can define macros, combos, and advanced features ZMK Studio doesn’t expose.
Want me to walk you through a clean, step-by-step “edit one key → rebuild → flash” example so you can try without breaking your board?
Here’s how it works:
1. Open your config repo The repo you set up for firmware (like
corne-wireless-zmk-config
or lily58-wireless-zmk-config
) has a config
folder.
2. Edit the keymap
Inside config
, you’ll see:
- corne.keymap
(for Corne)-
lily58.keymap
(for Lily58)This is your layout file. It’s just text that defines the layers and what keys go where. Example of a simplified layer section: -
&kp Q
means sending “Q” when you press that key.- You can also use things like
&mo 1
(momentary switch to layer 1), &bt BT_NXT
(cycle Bluetooth profile), etc. The full list of behaviors is in the ZMK keymap docs.
3. Commit and rebuild
- Once you edit *.keymap
, save + commit.- GitHub Actions will automatically rebuild your firmware.
- Download the new
.uf2
files from Actions → Artifacts.4. Flash your board Double-tap reset, copy new
.uf2
files to NICENANO
, done.
---
So, ZMK Studio = visual + runtime edits,while editing the keymap repo = full control, but needs reflashing.
👉 If you’re comfortable tinkering, the repo method is actually more powerful — you can define macros, combos, and advanced features ZMK Studio doesn’t expose.
Want me to walk you through a clean, step-by-step “edit one key → rebuild → flash” example so you can try without breaking your board?
Have a look at the layout editor, it's not dynamic, but more powerful than ZMK studio
oooooooo thanks avallee let me search it up on google
Keymap Editor
A web-based editor for ZMK Keymaps
essentially what it does is provide a web UI to edit your keymap file
the UI is pretty powerful, I was able to fully configure my layout with it, and I use some fancy external modules and behaviors
Don't forget to remove your ZMK studio stuff though, or reset your keyboard, as the dynamic stuff takes precedence over the firmware layout.
got a build error
-- Configuring incomplete, errors occurred!
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake -DWEST_PYTHON=/usr/bin/python3 -B/tmp/tmp.FcCfnW5Aek -GNinja -DBOARD=nice_nano_v2 -DZMK_CONFIG=/w/corne/corne/config '-DSHIELD=corne_right nice_view_adapter nice_view' -S/w/corne/corne/zmk/app
Error: Process completed with exit code 1.
Got it — thanks for pasting the build log, that helps 👌
The key part is this bit:
Notice how it has spaces inside? GitHub Actions / CMake doesn’t like that — it expects the SHIELD list to be a single, dash‑separated string, not multiple words.
For example:
✅ Correct (no spaces):
or in GitHub Actions YAML (most common setup):
If you just have:
the build system reads
- Make sure the
- For right half:
--- After committing that change, GitHub Actions should rebuild cleanly ✨
Do you want me to write out a clean example
The key part is this bit:
Notice how it has spaces inside? GitHub Actions / CMake doesn’t like that — it expects the SHIELD list to be a single, dash‑separated string, not multiple words.
For example:
✅ Correct (no spaces):
or in GitHub Actions YAML (most common setup):
If you just have:
the build system reads
corne_right
as the shield, and then crashes on nice_view_adapter
because it looks like a separate argument.
---
✅ Fix
- Open your GitHub repo
- Go to .github/workflows/build.yml
(or west.yml
if you edited manually)- Make sure the
-DSHIELD=...
line has quotes around the full shield string like this:
- For left half:- For right half:
--- After committing that change, GitHub Actions should rebuild cleanly ✨
Do you want me to write out a clean example
build.yml
job for Corne Wireless (left + right halves, with nice!view) so you can just copy/paste it?sorry i dont understand
No worries at all — let me break it down really simply 🙂
When GitHub Actions builds your firmware, it uses a "workflow file" (
The error is happening because your shield list (which tells ZMK what hardware you’re building for) has spaces but isn’t quoted.
Right now it looks like this ⬇️
The build system sees:
-
- but then thinks
--- ✅ How to fix You just need to put quotes (" ") around the whole thing so it’s treated as one value: Same idea for the left half: --- Where to change this 1. In your GitHub repo, open the file:
2. Find the lines under
3. Make sure the
- GitHub Actions will rerun
- This time it should succeed 🎉
--- 👉 Would you like me to paste a working example build.yml with both left + right halves (with nice!views) so you don’t have to edit yours manually?
When GitHub Actions builds your firmware, it uses a "workflow file" (
.github/workflows/build.yml
). That file tells it how to run the west build
command.The error is happening because your shield list (which tells ZMK what hardware you’re building for) has spaces but isn’t quoted.
Right now it looks like this ⬇️
The build system sees:
-
corne_right
(okay ✅)- but then thinks
nice_view_adapter
and nice_view
are random arguments ❌ → error--- ✅ How to fix You just need to put quotes (" ") around the whole thing so it’s treated as one value: Same idea for the left half: --- Where to change this 1. In your GitHub repo, open the file:
.github/workflows/build.yml
2. Find the lines under
run: west build ...
3. Make sure the
-DSHIELD=...
part looks like the “✅ fixed” version above.
---
After you commit that change:- GitHub Actions will rerun
- This time it should succeed 🎉
--- 👉 Would you like me to paste a working example build.yml with both left + right halves (with nice!views) so you don’t have to edit yours manually?
why is this an error? I havent touched anything like that
Good question 👍 — if you didn’t touch it, then this is likely caused by how the SHIELD string got passed into the build by GitHub Actions.
Here’s what happens under the hood:
- ZMK needs to know which “shield(s)” (hardware pieces) you’re building for.
- For a Corne with nice!view, that means:
-
-
-
- These must be passed as a single parameter to CMake, like:
- Without the quotes, the system misparses them:
-
-
-
The reason you’re seeing this now is probably because:
- You used a template repo for nice!view, but GitHub sometimes strips the quotes in YAML parsing.
- Or the workflow file was copied from a non–nice!view config (those only have one shield, e.g.
So: you didn’t break it, the issue is just that
--- 👉 If you want, I can paste the corrected
Here’s what happens under the hood:
- ZMK needs to know which “shield(s)” (hardware pieces) you’re building for.
- For a Corne with nice!view, that means:
-
corne_right
(or corne_left
)-
nice_view_adapter
-
nice_view
- These must be passed as a single parameter to CMake, like:
- Without the quotes, the system misparses them:
-
-DSHIELD=corne_right
(gets read fine ✅)-
nice_view_adapter
(unexpected ❌)-
nice_view
(unexpected ❌)The reason you’re seeing this now is probably because:
- You used a template repo for nice!view, but GitHub sometimes strips the quotes in YAML parsing.
- Or the workflow file was copied from a non–nice!view config (those only have one shield, e.g.
corne_left
), so quotes weren’t needed until multiple shields were added.So: you didn’t break it, the issue is just that
build.yml
expects one shield, but for nice!view we need three. Quoting groups them together.--- 👉 If you want, I can paste the corrected
build.yml
snippet (left and right halves, with nice!view) so you can just replace yours. Would that help?sure
sure
Perfect 👌 — here’s a clean
Make sure it lives at
- Uses quotes around all shields so CMake parses them correctly.
- Uploads
--- If you’re using a Lily58 Wireless with nice!view, you’d just swap
👉 Do you want me to also show the non-nice!view
build.yml
snippet you can drop into your repo that will build both halves of a Corne Wireless with nice!view.Make sure it lives at
.github/workflows/build.yml
in your repo:
📝 What this does
- Builds twice: once for the left half (corne_left ...
) and once for the right half (corne_right ...
).- Uses quotes around all shields so CMake parses them correctly.
- Uploads
.uf2
files as artifacts you can download per half.--- If you’re using a Lily58 Wireless with nice!view, you’d just swap
corne_left/corne_right
for lily58_left/lily58_right
.👉 Do you want me to also show the non-nice!view
build.yml
(simpler shields) so you have both for reference?didn't work. This is what's in the build.yaml file
This file generates the GitHub Actions matrix
For simple board + shield combinations, add them
to the top level board and shield arrays, for more
control, add individual board + shield combinations to
the
include
property, e.g:
board: [ "nice_nano_v2" ]
shield: [ "corne_left", "corne_right" ]
include:
- board: bdn9_rev2
- board: nice_nano_v2
shield: reviung41
---
include:
- board: nice_nano_v2
shield: corne_left nice_view_adapter nice_view
snippet: studio-rpc-usb-uart
- board: nice_nano_v2
shield: corne_right nice_view_adapter nice_viewAhhh I see what’s happening now 🙌 — thanks for pasting your actual
The problem is in how shield values are written in YAML: when you have multiple shields (like
So your file should look like this: 🔑 What changed - I added quotes (
- That way GitHub passes them correctly to cmake as one single parameter.
--- ⚡️ After you commit and push this change, GitHub Actions should rebuild cleanly and give you two artifacts: -
build.yaml
.The problem is in how shield values are written in YAML: when you have multiple shields (like
corne_left nice_view_adapter nice_view
), they must be quoted as a single string. Otherwise YAML splits them and CMake explodes.So your file should look like this: 🔑 What changed - I added quotes (
" "
) around the shield values with spaces.- That way GitHub passes them correctly to cmake as one single parameter.
--- ⚡️ After you commit and push this change, GitHub Actions should rebuild cleanly and give you two artifacts: -
firmware-corne_left...uf2
- firmware-corne_right...uf2
---
Would you like me to also show what to put if you don’t use nice!view (so you can swap between the two quickly without editing a lot)?still not working even with the code snippet you gave
Got it 👍 thanks for confirming — let’s carefully dig into this so it works for you.
The key is:
That’s why it’s still failing.
--- ✅ Correct
- OR a list:
- Using a space‑separated string confuses YAML or gets parsed wrong before cmake.
--- 👉 Try replacing your
That should finally stop cmake from choking and let the workflow build both halves with nice!view.
Do you want me to also give you the non‑nice!view version of
The key is:
build.yaml
uses arrays, not space‑separated strings. When you have multiple shields (like corne_left + nice_view_adapter + nice_view
), they need to be written as a YAML list instead of one long string, even with quotes.That’s why it’s still failing.
--- ✅ Correct
build.yaml
syntax with shields as a list
Why this works
- In ZMK’s GitHub Action templates, shield:
can take either:
- shield: corne_left
(single shield)- OR a list:
- Using a space‑separated string confuses YAML or gets parsed wrong before cmake.
--- 👉 Try replacing your
build.yaml
shields with the list version above, commit, and push.That should finally stop cmake from choking and let the workflow build both halves with nice!view.
Do you want me to also give you the non‑nice!view version of
build.yaml
(just corne_left
/corne_right
) for quick swapping?Error: The template is not valid. zmkfirmware/zmk/.github/workflows/build-user-config.yml@main (Line: 63, Col: 19): A sequence was not expected
Ahhh 👌 this clarifies it — you’re using the
So here’s the correct fix for your
❌ No dashes/- for each shield, no array.
--- Why the last attempt failed - When you wrote it as a YAML list (
- When you wrote with spaces but no quotes, YAML treated the values incorrectly and CMake crashed.
So the correct syntax is exactly the one above:
--- 👉 Replace your current
That should finally let the builds succeed for both halves.
Would you like me to also paste a working no‑nice!view variant side‑by‑side so you can swap quickly if you ever rebuild without screens?
build-user-config.yml
template from ZMK. That one does not allow lists for shield
. It’s strict: shield
must be a single string.So here’s the correct fix for your
build.yaml
(not as a YAML sequence, but keep all shields in one quoted string). Your file should be:
✅ Important: Quotes around the entire "corne_left nice_view_adapter nice_view"
.❌ No dashes/- for each shield, no array.
--- Why the last attempt failed - When you wrote it as a YAML list (
- corne_left ...
), the template expected just a string, not a sequence. That’s why GitHub Actions threw sequence not expected
.- When you wrote with spaces but no quotes, YAML treated the values incorrectly and CMake crashed.
So the correct syntax is exactly the one above:
--- 👉 Replace your current
build.yaml
contents with that version, commit, and push.That should finally let the builds succeed for both halves.
Would you like me to also paste a working no‑nice!view variant side‑by‑side so you can swap quickly if you ever rebuild without screens?
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake -DWEST_PYTHON=/usr/bin/python3 -B/tmp/tmp.zIuj9kWfmb -GNinja -DBOARD=nice_nano_v2 -DZMK_CONFIG=/w/corne/corne/config '-DSHIELD=corne_right nice_view_adapter nice_view' -S/w/corne/corne/zmk/app
Error: Process completed with exit code 1.
Got it — thanks for sticking with me while we narrow it down 🔍.
That build line (
The official repos use repositories pre‑set for nice!view builds instead of stacking shields manually. This avoids YAML quoting issues. --- ✅ Two safer options: Option 1: Use Typeractive’s pre‑set config repos (recommended)
Instead of writing
- Corne Wireless + nice!view
- Corne Wireless (no view)
These already have the correct syntax so you can just adjust your
Notice the
(Functions the same as
Would you like me to paste the full working
That build line (
'-DSHIELD=corne_right nice_view_adapter nice_view'
) looks exactly correct… but here’s the catch:
👉 For shields with multiple parts (like corne_right + nice_view_adapter + nice_view
), you normally need the multi‑shield notation ZMK expects.The official repos use repositories pre‑set for nice!view builds instead of stacking shields manually. This avoids YAML quoting issues. --- ✅ Two safer options: Option 1: Use Typeractive’s pre‑set config repos (recommended)
Instead of writing
build.yaml
yourself, fork our ready repos:- Corne Wireless + nice!view
- Corne Wireless (no view)
These already have the correct syntax so you can just adjust your
corne.keymap
and push. Builds will work with no YAML headaches.
---
Option 2: Force cmake to treat the whole shield parameter as one stringNotice the
+
— this is the syntax ZMK supports internally for multi‑shield builds.(Functions the same as
"corne_left nice_view_adapter nice_view"
, but parses more cleanly with the templates.)
---
👉 My suggestion: if you want the simplest fix right now, use Option 2 with the +
signs. Commit & push, and the Actions run should stop failing.Would you like me to paste the full working
build.yaml
with + syntax so you can copy/paste directly?GitHub
GitHub - typeractivexyz/corne-wireless-view-zmk-config
Contribute to typeractivexyz/corne-wireless-view-zmk-config development by creating an account on GitHub.
GitHub
GitHub - typeractivexyz/corne-wireless-zmk-config
Contribute to typeractivexyz/corne-wireless-zmk-config development by creating an account on GitHub.
reverted back to the yaml of the original repository however
-- Configuring incomplete, errors occurred!
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake -DWEST_PYTHON=/usr/bin/python3 -B/tmp/tmp.22RllfG1JS -GNinja -DBOARD=nice_nano_v2 -DZMK_CONFIG=/w/corne/corne/config '-DSHIELD=corne_left nice_view_adapter nice_view' -DSNIPPET=studio-rpc-usb-uart -S/w/corne/corne/zmk/app
Error: Process completed with exit code 1.
-- Configuring incomplete, errors occurred!
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake -DWEST_PYTHON=/usr/bin/python3 -B/tmp/tmp.dizAnC0xpL -GNinja -DBOARD=nice_nano_v2 -DZMK_CONFIG=/w/corne/corne/config '-DSHIELD=corne_right nice_view_adapter nice_view' -S/w/corne/corne/zmk/app
Error: Process completed with exit code 1.
Thanks for showing the exact log again — now it clicks ✅.
The shields themselves are fine (
That’s why the Typeractive docs point you to our pre‑made template repos — they already have the correct layout, overlays, and build config set up.
--- 🔑 How to fix cleanly Instead of fighting the YAML / cmake, start from one of our working templates: - Corne Wireless with nice!view:
https://github.com/typeractivexyz/corne-wireless-view-zmk-config
- Corne Wireless without nice!view:
https://github.com/typeractivexyz/corne-wireless-zmk-config
1. Click “Use this template” in the repo (to make your own copy).
2. Edit only the
3. Push your changes — GitHub Actions will automatically build firmware for both halves and upload
--- Why your current setup fails The “vanilla” ZMK repo doesn’t include Typeractive’s multi‑shield configs (like
--- 👉 Easiest path forward: fork the repo above that matches your build (with or without nice!view). Then only touch your
Would you like me to walk you through starting that fresh
The shields themselves are fine (
corne_left/right nice_view_adapter nice_view
) — the error is that your repo is still pointing at the plain ZMK source (zmk/app
) which doesn’t know about those multi‑shield combos unless the right board overlays/configs are present.That’s why the Typeractive docs point you to our pre‑made template repos — they already have the correct layout, overlays, and build config set up.
--- 🔑 How to fix cleanly Instead of fighting the YAML / cmake, start from one of our working templates: - Corne Wireless with nice!view:
https://github.com/typeractivexyz/corne-wireless-view-zmk-config
- Corne Wireless without nice!view:
https://github.com/typeractivexyz/corne-wireless-zmk-config
1. Click “Use this template” in the repo (to make your own copy).
2. Edit only the
config/corne.keymap
file to customize your layout.3. Push your changes — GitHub Actions will automatically build firmware for both halves and upload
.uf2
files.--- Why your current setup fails The “vanilla” ZMK repo doesn’t include Typeractive’s multi‑shield configs (like
nice_view_adapter
). That’s why cmake bails out even though your YAML looks right.--- 👉 Easiest path forward: fork the repo above that matches your build (with or without nice!view). Then only touch your
keymap
. The builds will just work 👍Would you like me to walk you through starting that fresh
view
config repo step‑by‑step so you can be sure it’s set up correctly?GitHub
GitHub - typeractivexyz/corne-wireless-view-zmk-config
Contribute to typeractivexyz/corne-wireless-view-zmk-config development by creating an account on GitHub.
GitHub
GitHub - typeractivexyz/corne-wireless-zmk-config
Contribute to typeractivexyz/corne-wireless-zmk-config development by creating an account on GitHub.
i did use those. I edited using Keymap Editor. Was I not supposed to delete the original layers provided or something?
Ahh — that explains it 🎯
You did start from the correct Typeractive config repo, so the shields + YAML are fine. The problem is now inside your keymap edits. What happened When you edited with Keymap Editor, it rewrote
If you deleted the original top‑section (like
If that structure or required bindings (like BT keys) are missing, config generation fails. --- ✅ How to fix 1. Grab a fresh copy of
- Example: corne-wireless-view-zmk-config → config/corne.keymap 2. Copy that back into your repo. 3. Re‑apply your edits via Keymap Editor but keep the structure / layers in place.
- You can remove layers you don’t want, but don’t delete the wrapping
- One base layer
- Any required ZMK system bindings like
--- 📝 In short Yes — you probably deleted something critical, not just “extra” layers.
Start from a clean template
You did start from the correct Typeractive config repo, so the shields + YAML are fine. The problem is now inside your keymap edits. What happened When you edited with Keymap Editor, it rewrote
corne.keymap
.If you deleted the original top‑section (like
default_layer
, &bt BT_CLR
, etc.) or if the file is now malformed YAML/dtsi, CMake will fail before even compiling — exactly what you're seeing.
ZMK expects:
- A keymap
node defined properly.
- At least one base layer.
- The include at the top like:If that structure or required bindings (like BT keys) are missing, config generation fails. --- ✅ How to fix 1. Grab a fresh copy of
corne.keymap
from the template you forked:- Example: corne-wireless-view-zmk-config → config/corne.keymap 2. Copy that back into your repo. 3. Re‑apply your edits via Keymap Editor but keep the structure / layers in place.
- You can remove layers you don’t want, but don’t delete the wrapping
keymap { ... };
- At minimum, you need:- One base layer
- Any required ZMK system bindings like
&bt BT_CLR
, &bt BT_NXT
somewhere (otherwise you lose BT control)--- 📝 In short Yes — you probably deleted something critical, not just “extra” layers.
Start from a clean template
corne.keymap
, then carefully re‑add your custom layout instead of replacing the whole file.
---
👉 Do you want me to paste the minimal “safe” corne.keymap skeleton that compiles fine, so you can use it as a base before adding your own layout?there are required bindings? What are they and why are they required
Great question 🙌 — yes, there are some bindings that are strongly recommended (almost “required”) for a wireless ZMK build, especially with splits like the Corne / Lily58.
--- 🔑 Why you need them - ZMK manages Bluetooth profiles, pairing, and half‑to‑half communication.
- If you delete the special keycodes, your keyboard firmware can still build — but you’ll have no way to pair, clear, or switch devices. That’s why template keymaps include them by default.
--- 🛠 The important bindings -
Clears the current Bluetooth bond for the active profile.
→ Needed if you ever want to re‑pair with a new device.
-
Cycle through ZMK’s 5 available BLE profiles.
→ Lets you connect to multiple devices (laptop, tablet, phone).
-
Selects a specific profile (0–4).
-
Soft‑resets the keyboard. Useful but not strictly required.
- Layer switching keys (like
→ Not “required” in the firmware sense, but without them you’d be stuck on one layer.
--- ✅ Minimal must‑keep At least keep: -
So you’re able to pair/re‑pair devices.
--- ⚡️ What’s optional - You can trim down extra layers, or change how layer switching works.
- You can remove things like RGB keys if you don’t use them.
But if you delete every BT control key, you’ll eventually have to reflash firmware just to reconnect your board 😅
--- 👉 Recommendation: Restore the template keymap, keep those BT management bindings somewhere (even if hidden on a function layer), then customize around them.
Do you want me to paste a minimal compiling Corne example keymap with just
--- 🔑 Why you need them - ZMK manages Bluetooth profiles, pairing, and half‑to‑half communication.
- If you delete the special keycodes, your keyboard firmware can still build — but you’ll have no way to pair, clear, or switch devices. That’s why template keymaps include them by default.
--- 🛠 The important bindings -
&bt BT_CLR
Clears the current Bluetooth bond for the active profile.
→ Needed if you ever want to re‑pair with a new device.
-
&bt BT_NXT
/ &bt BT_PRV
Cycle through ZMK’s 5 available BLE profiles.
→ Lets you connect to multiple devices (laptop, tablet, phone).
-
&bt BT_SEL <n>
Selects a specific profile (0–4).
-
&reset
(sometimes included)Soft‑resets the keyboard. Useful but not strictly required.
- Layer switching keys (like
&mo
, <
, &tog
)→ Not “required” in the firmware sense, but without them you’d be stuck on one layer.
--- ✅ Minimal must‑keep At least keep: -
&bt BT_CLR
- Either &bt BT_NXT
/ &bt BT_PRV
or &bt BT_SEL <n>
So you’re able to pair/re‑pair devices.
--- ⚡️ What’s optional - You can trim down extra layers, or change how layer switching works.
- You can remove things like RGB keys if you don’t use them.
But if you delete every BT control key, you’ll eventually have to reflash firmware just to reconnect your board 😅
--- 👉 Recommendation: Restore the template keymap, keep those BT management bindings somewhere (even if hidden on a function layer), then customize around them.
Do you want me to paste a minimal compiling Corne example keymap with just
QWERTY + FN layer
and those required Bluetooth keys? That way you’ll have a clean base again.-- In: /tmp/tmp.xE0EPvwsAa/zephyr, command: /usr/bin/python3;/w/corne/corne/zephyr/scripts/dts/gen_defines.py;--dts;/tmp/tmp.xE0EPvwsAa/zephyr/zephyr.dts.pre;--dtc-flags;'-Wno-unique_unit_address_if_enabled';--bindings-dirs;/w/corne/corne/zmk/app/module/dts/bindings;/w/corne/corne/zmk/app/dts/bindings;/w/corne/corne/zephyr/dts/bindings;--header-out;/tmp/tmp.xE0EPvwsAa/zephyr/include/generated/devicetree_generated.h.new;--dts-out;/tmp/tmp.xE0EPvwsAa/zephyr/zephyr.dts.new;--edt-pickle-out;/tmp/tmp.xE0EPvwsAa/zephyr/edt.pickle;--vendor-prefixes;/w/corne/corne/zmk/app/dts/bindings/vendor-prefixes.txt;--vendor-prefixes;/w/corne/corne/zephyr/dts/bindings/vendor-prefixes.txt
-- Configuring incomplete, errors occurred!
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake -DWEST_PYTHON=/usr/bin/python3 -B/tmp/tmp.xE0EPvwsAa -GNinja -DBOARD=nice_nano_v2 -DZMK_CONFIG=/w/corne/corne/config '-DSHIELD=corne_right nice_view_adapter nice_view' -S/w/corne/corne/zmk/app
Error: Process completed with exit code 1.
i added bt clear and next but still
-- In: /tmp/tmp.G9Jz4xDiYL/zephyr, command: /usr/bin/python3;/w/corne/corne/zephyr/scripts/dts/gen_defines.py;--dts;/tmp/tmp.G9Jz4xDiYL/zephyr/zephyr.dts.pre;--dtc-flags;'-Wno-unique_unit_address_if_enabled';--bindings-dirs;/w/corne/corne/zmk/app/module/dts/bindings;/w/corne/corne/zmk/app/dts/bindings;/w/corne/corne/zephyr/dts/bindings;--header-out;/tmp/tmp.G9Jz4xDiYL/zephyr/include/generated/devicetree_generated.h.new;--dts-out;/tmp/tmp.G9Jz4xDiYL/zephyr/zephyr.dts.new;--edt-pickle-out;/tmp/tmp.G9Jz4xDiYL/zephyr/edt.pickle;--vendor-prefixes;/w/corne/corne/zmk/app/dts/bindings/vendor-prefixes.txt;--vendor-prefixes;/w/corne/corne/zephyr/dts/bindings/vendor-prefixes.txt
-- Configuring incomplete, errors occurred!
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake -DWEST_PYTHON=/usr/bin/python3 -B/tmp/tmp.G9Jz4xDiYL -GNinja -DBOARD=nice_nano_v2 -DZMK_CONFIG=/w/corne/corne/config '-DSHIELD=corne_left nice_view_adapter nice_view' -DSNIPPET=studio-rpc-usb-uart -S/w/corne/corne/zmk/app
Error: Process completed with exit code 1.
i added bt clear and next but still
-- In: /tmp/tmp.G9Jz4xDiYL/zephyr, command: /usr/bin/python3;/w/corne/corne/zephyr/scripts/dts/gen_defines.py;--dts;/tmp/tmp.G9Jz4xDiYL/zephyr/zephyr.dts.pre;--dtc-flags;'-Wno-unique_unit_address_if_enabled';--bindings-dirs;/w/corne/corne/zmk/app/module/dts/bindings;/w/corne/corne/zmk/app/dts/bindings;/w/corne/corne/zephyr/dts/bindings;--header-out;/tmp/tmp.G9Jz4xDiYL/zephyr/include/generated/devicetree_generated.h.new;--dts-out;/tmp/tmp.G9Jz4xDiYL/zephyr/zephyr.dts.new;--edt-pickle-out;/tmp/tmp.G9Jz4xDiYL/zephyr/edt.pickle;--vendor-prefixes;/w/corne/corne/zmk/app/dts/bindings/vendor-prefixes.txt;--vendor-prefixes;/w/corne/corne/zephyr/dts/bindings/vendor-prefixes.txt
-- Configuring incomplete, errors occurred!
FATAL ERROR: command exited with status 1: /usr/local/bin/cmake -DWEST_PYTHON=/usr/bin/python3 -B/tmp/tmp.G9Jz4xDiYL -GNinja -DBOARD=nice_nano_v2 -DZMK_CONFIG=/w/corne/corne/config '-DSHIELD=corne_left nice_view_adapter nice_view' -DSNIPPET=studio-rpc-usb-uart -S/w/corne/corne/zmk/app
Error: Process completed with exit code 1.
Thanks for the extra logs — this is really helpful.
👉 What’s happening now is not about missing
The build is failing very early, during device‑tree (
- CMake fails with:
→ This means one of those shields isn’t being found, so Devicetree can’t be generated. --- 🔑 The fix This is where the confusion comes in:
- If you are truly using the Typeractive template repos (corne-wireless-view-zmk-config), then you do not need to manually touch the
- Our repo already has the shields (
If you edited
- Either re‑fork the repo, or copy the original
3. Commit and push — Actions should build both halves cleanly. --- Why this works - The template repo already has the special shield combo stitched in.
- If you add or mis‑quote shields in
- The repeated error messages you see are exactly what happens when cmake can’t resolve
Would you like me to paste the exact untouched
👉 What’s happening now is not about missing
&bt
keys anymore.The build is failing very early, during device‑tree (
.dts
) generation, because CMake can’t resolve your shield combination.
---
What this means
- The error occurs before keymap parsing.- CMake fails with:
→ This means one of those shields isn’t being found, so Devicetree can’t be generated. --- 🔑 The fix This is where the confusion comes in:
- If you are truly using the Typeractive template repos (corne-wireless-view-zmk-config), then you do not need to manually touch the
build.yaml
shield list.- Our repo already has the shields (
corne_left/right nice_view_adapter nice_view
) configured correctly.If you edited
build.yaml
at all, revert it back to its original form from the template repo.
---
What you should do
1. Reclone / reset your fork back to the clean template.- Either re‑fork the repo, or copy the original
build.yaml
back in.
2. Only edit your config/corne.keymap
file. Do not change build.yaml
.3. Commit and push — Actions should build both halves cleanly. --- Why this works - The template repo already has the special shield combo stitched in.
- If you add or mis‑quote shields in
build.yaml
, it breaks the workflow.- The repeated error messages you see are exactly what happens when cmake can’t resolve
nice_view_adapter
because YAML or shield passing was changed.
---
✅ So: restore the original build.yaml
, undo changes there, and limit changes to your corne.keymap
.Would you like me to paste the exact untouched
build.yaml
from the template so you can compare line‑for‑line with yours and fix it quickly?all of this is with the original build.yaml code already
all of this is with the original build.yaml code already
all of this is with the original build.yaml code already
Thanks for clarifying 🙏 — if you’re on the original untouched Typeractive template repo and still seeing this error, that means the problem isn’t in
The log: is exactly what happens when
- If the
- This fits with what you described: editing in Keymap Editor and maybe deleting too much.
2. Accidentally removed include lines at the top of your
These must stay.
3. Stray characters (tabs, quotes, unusual hyphens) from copy/paste or a bad Keymap Editor export.
--- ✅ How to recover 1. Pull a fresh original
- Don’t touch
2. Commit & push → verify it builds.
- If it compiles clean, then you know the cause was your edited keymap.
3. Re‑apply your layout gradually: - Edit one layer at a time in Keymap Editor.
- Push, check if CI still builds.
- If an edit breaks the build, you can pinpoint the exact layer/binding causing problems.
--- 📝 Key takeaway The
--- 👉 Do you want me to paste a minimal safe
build.yaml
at all.The log: is exactly what happens when
CMake
/west
cannot find one of the shields listed. Since the template repo builds fine “out of the box,” the most common reasons are:
---
🔎 Common causes
1. Keymap file syntax broken- If the
.keymap
file has a missing brace, semicolon, or invalid binding, CMake bails out during devicetree parsing.- This fits with what you described: editing in Keymap Editor and maybe deleting too much.
2. Accidentally removed include lines at the top of your
corne.keymap
:These must stay.
3. Stray characters (tabs, quotes, unusual hyphens) from copy/paste or a bad Keymap Editor export.
--- ✅ How to recover 1. Pull a fresh original
config/corne.keymap
from the Typeractive repo.- Don’t touch
build.yaml
.2. Commit & push → verify it builds.
- If it compiles clean, then you know the cause was your edited keymap.
3. Re‑apply your layout gradually: - Edit one layer at a time in Keymap Editor.
- Push, check if CI still builds.
- If an edit breaks the build, you can pinpoint the exact layer/binding causing problems.
--- 📝 Key takeaway The
build.yaml
is already correct. Your issue is almost certainly malformed corne.keymap
(missing wrapping structure, unmatched braces, or bad binding).--- 👉 Do you want me to paste a minimal safe
corne.keymap
skeleton (compiles, has BT keys, only a simple base + FN layer) so you can drop it in as a reset point and rebuild from there? That will quickly confirm it’s the keymap syntax causing the build to crash.sigh