Troubleshooting
Trace mounting, bindings, component inputs, and cleanup problems from symptom to cause.
Use this page as a symptom -> cause -> fix reference based on current Regor runtime behavior.
Start with the smallest failing interaction. Follow its state from context to DOM.
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
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')! })
// or
createApp(ctx, { selector: '#app' }) If you use createApp(ctx, '<div>...</div>'), Regor expects a real #app in DOM.
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
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
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). Also note that omitted declared prop names are not isolated automatically in that mode, so same-named parent values can still resolve through normal template lookup.
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
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
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
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
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.
Keep the mount target, state, and one failing binding. Include the Regor version and browser when sharing the reproduction.
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.