Troubleshooting
Use this page as a symptom -> cause -> fix reference based on current Regor runtime behavior.
Quick Triage
Section titled “Quick Triage”Before deep debugging:
- Verify root exists and app actually mounted.
- Verify template is the one you think is mounted (selector/element/string/json path).
- Verify binding channel is correct (
:xvs:contextvsr-bind="{...}"). - Verify scope/hook usage (
useScopefor composables). - Verify teardown timing (
unmount+drainUnbindin tests).
App Does Not Mount
Section titled “App Does Not Mount”Symptom:
createAppthrows and nothing renders.
Likely cause:
- Missing root element.
Runtime error:
createApp can't find root element...
Fix:
createApp(ctx, { element: document.querySelector('#app')! })// orcreateApp(ctx, { selector: '#app' })If you use createApp(ctx, '<div>...</div>'), Regor expects a real #app in DOM.
onMounted / onUnmounted Throws
Section titled “onMounted / onUnmounted Throws”Symptom:
- Error about composables requiring scope.
Likely cause:
- Hook registered outside active scope.
Runtime error:
Use composables in scope. usage: useScope(() => new MyApp())
Fix:
createApp( useScope(() => { onMounted(() => {}) onUnmounted(() => {}) return { count: ref(0) } }), { element: root },)Interpolation Not Updating
Section titled “Interpolation Not Updating”Symptom:
{{ expr }}/[[ expr ]]appears as raw text.
Likely causes:
config.useInterpolation = false- Markup is under
r-pre - Expression resolves to missing path/value
Fix checklist:
- Enable interpolation (
RegorConfig.useInterpolation = true) when needed. - Remove
r-prefrom dynamic subtree. - Confirm expression resolves in active context.
Component Inputs Not Reaching Context
Section titled “Component Inputs Not Reaching Context”Most confusion here comes from input channel mismatch.
Correct routing:
:x/.x/r-bind:x: works as component prop only whenxis declared inprops.:context/r-context: object-style component input channel.r-bind="{...}"(object form): attribute channel on component hosts (fallthrough), nothead.propsobject assignment.
If component sets head.autoProps = false, you must map head.props manually in context(head).
Parent-Child Ref Sync Feels Wrong
Section titled “Parent-Child Ref Sync Feels Wrong”Check head.entangle semantics:
head.entangle = true: ref-to-ref inputs are two-way entangled.head.entangle = false: ref-to-ref inputs are snapshot-only (no persistent sync).
Also check whether parent sends ref source vs primitive expression:
:context="{ x: someRef }"behaves differently from:context="{ x: someRef + 1 }".
Slot Expression Uses Wrong Context
Section titled “Slot Expression Uses Wrong Context”Symptom:
- Slot content appears to evaluate against child context instead of parent.
Fix:
- Enable slot context switching in component:
context: (head) => { head.enableSwitch = true return {}}Then verify slot naming matches (name / #name).
r-for Updates Look Broken
Section titled “r-for Updates Look Broken”Checklist:
- Use stable identity keys (
:key="row.id"orkey="row.id"). - Ensure key is unique and stable across updates.
- Avoid mutating key identity unexpectedly between renders.
Cleanup / Memory / Test Flakiness
Section titled “Cleanup / Memory / Test Flakiness”Know the teardown difference:
app.unmount()removes root node and queues unbind flush.app.unbind()detaches bindings without removing DOM.
In tests, if assertions depend on cleanup side effects:
app.unmount()await drainUnbind()Warnings You Should Not Ignore
Section titled “Warnings You Should Not Ignore”Frequent warning types and meaning:
- Missing binding expression: directive attribute exists but expression is empty.
- Invalid
r-forexpression: loop syntax is malformed. - Binding requires object expression: directive expected object input (for example object-style binding paths).
- Key is empty: dynamic key path resolved to empty key.
- Model requires ref / unsupported element:
r-modeltarget is invalid for current element/source.
When Reporting an Issue
Section titled “When Reporting an Issue”Include:
- Minimal template + context snippet.
- Expected result vs actual result.
- Which channel you used (
:x,r-bind:x,:context,r-context,r-bind="{...}"). - Whether problem persists after
unmount+await drainUnbind(). - Regor version + runtime environment.