sveltejs/svelte · error · Error
bind_not_bindable
bind_not_bindable
Error message
bind_not_bindable
A component is attempting to bind to a non-bindable property `${key}` belonging to ${component} (i.e. `<${name} bind:${key}={...}>`). To mark a property as bindable: `let { ${key} = $bindable() } = $props()`
https://svelte.dev/e/bind_not_bindable What it means
Runtime error `bind_not_bindable`: similar to `bind_invalid_export` but raised when binding to a property that is not declared as a prop at all (not just not bindable). The message includes a hint showing exactly how to declare it bindable: `let { key = $bindable() } = $props()`.
Source
Thrown at packages/svelte/src/internal/client/errors.js:71
} else {
throw new Error(`https://svelte.dev/e/bind_invalid_export`);
}
}
/**
* A component is attempting to bind to a non-bindable property `%key%` belonging to %component% (i.e. `<%name% bind:%key%={...}>`). To mark a property as bindable: `let { %key% = $bindable() } = $props()`
* @param {string} key
* @param {string} component
* @param {string} name
* @returns {never}
*/
export function bind_not_bindable(key, component, name) {
if (DEV) {
const error = new Error(`bind_not_bindable\nA component is attempting to bind to a non-bindable property \`${key}\` belonging to ${component} (i.e. \`<${name} bind:${key}={...}>\`). To mark a property as bindable: \`let { ${key} = $bindable() } = $props()\`\nhttps://svelte.dev/e/bind_not_bindable`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/bind_not_bindable`);
}
}
/**
* Calling `%method%` on a component instance (of %component%) is no longer valid in Svelte 5
* @param {string} method
* @param {string} component
* @returns {never}
*/
export function component_api_changed(method, component) {
if (DEV) {
const error = new Error(`component_api_changed\nCalling \`${method}\` on a component instance (of ${component}) is no longer valid in Svelte 5\nhttps://svelte.dev/e/component_api_changed`);
error.name = 'Svelte error';
throw error;View on GitHub (pinned to 20b341f100)
Solutions
- Declare the prop as bindable in the target component: `let { foo = $bindable() } = $props()`.
- Verify the bound key name matches a declared prop (check for typos / renames).
- If binding is unintended, remove `bind:` and pass the prop one-way.
Example fix
// before
<!-- consumer -->
<Slider bind:value={v} />
<!-- Slider.svelte -->
<script>
let { value } = $props();
</script>
// after
<script>
let { value = $bindable() } = $props();
</script> Defensive patterns
Strategy: validation
Validate before calling
// Verify the bound key exists as a $bindable prop in the target component.
function assertBindable(targetSource, key) {
const re = new RegExp(`\\b(?:let|const)\\s*\\{[^}]*\\b${key}\\b[^}]*=\\s*\\$bindable`);
if (!re.test(targetSource)) {
throw new Error(`${key} is not a bindable prop on the target component`);
}
} Prevention
- Declare every two-way-bound prop with `$bindable()` in the child.
- Double-check bound key spelling against the child's declared props.
- Reserve `bind:` for props you actually need to mutate from the parent.
When it happens
Trigger: At runtime (DEV) when a consumer does `<Comp bind:foo={...}/>` and `Comp` does not expose `foo` as a bindable prop (either not declared, or declared without `$bindable()`).
Common situations: Binding to a prop that was renamed or removed during migration; binding to internal state that was never intended to be a public prop; typos in the bound key.
Related errors
- bind_invalid_export
- bind_invalid_checkbox_value
- Encountered an export declaration pattern that is not suppor
- $$props is used together with named props in a way that cann
- async_derived_orphan
AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12).
Data as JSON: /api/errors/5ccc581a5d87ae47.
Report an issue: GitHub.