diff --git a/src/pages/docs/liveobjects/batch.mdx b/src/pages/docs/liveobjects/batch.mdx
index 4d173ce388..4de143c36b 100644
--- a/src/pages/docs/liveobjects/batch.mdx
+++ b/src/pages/docs/liveobjects/batch.mdx
@@ -80,7 +80,7 @@ await rootObject.get('visits').batch((ctx) => {
When you call `batch()` on a `PathObject`, the path is resolved to its underlying instance, and the batch context operates on that resolved instance.
-You can only call `batch()` on an `PathObject` whose path resolves to a `LiveMap` or `LiveCounter` instance:
+You can only call `batch()` on a `PathObject` whose path resolves to a `LiveMap` or `LiveCounter` instance:
```javascript
diff --git a/src/pages/docs/liveobjects/concepts/instance.mdx b/src/pages/docs/liveobjects/concepts/instance.mdx
index 68122576bc..15727973b7 100644
--- a/src/pages/docs/liveobjects/concepts/instance.mdx
+++ b/src/pages/docs/liveobjects/concepts/instance.mdx
@@ -27,6 +27,8 @@ meta_description: "Learn about Instance, a reference to a specific LiveObject in
An `Instance` represents a specific object instance within the channel object. When you call methods on an `Instance`, they operate on that specific instance regardless of where it exists in the structure or whether it has been moved.
+An `Instance` can also wrap a primitive value, for example when obtained from a path that resolves to a primitive. Primitive-backed instances are read-only and have no object ID.
+
-The `instance()` method returns `undefined` if no object exists at that path.
+The `instance()` method returns `undefined` only if nothing exists at that path. It wraps whatever value resolves there: a `LiveMap`, a `LiveCounter`, or a primitive value. A primitive-backed `Instance` is read-only: it has no `id` and exposes the primitive via `value()`.
The `instance()` method returns `null` only if nothing exists at that path. It wraps whatever value resolves there: a `LiveMap` or `LiveCounter` becomes a `LiveMapInstance` or `LiveCounterInstance`, and a primitive value becomes a read-only primitive instance (for example `StringInstance`).
@@ -202,7 +204,7 @@ if (settingsInstance != null) {
-The `id` getter returns the [object ID](/docs/liveobjects/concepts/objects#object-ids) of the instance, which can be used with the [REST API](/docs/liveobjects/rest-api-usage).
+The `id` getter returns the [object ID](/docs/liveobjects/concepts/objects#object-ids) of the instance, which can be used with the [REST API](/docs/liveobjects/rest-api-usage). On a primitive-backed instance, `id` returns `undefined`, because primitives have no object ID.
The `getId()` method returns the [object ID](/docs/liveobjects/concepts/objects?lang=java#object-ids) of the instance, which can be used with the [REST API](/docs/liveobjects/rest-api-usage).
diff --git a/src/pages/docs/liveobjects/concepts/objects.mdx b/src/pages/docs/liveobjects/concepts/objects.mdx
index 175de81967..5ffb193c3c 100644
--- a/src/pages/docs/liveobjects/concepts/objects.mdx
+++ b/src/pages/docs/liveobjects/concepts/objects.mdx
@@ -248,7 +248,7 @@ See the [PathObject documentation](/docs/liveobjects/concepts/path-object) for d
const rootObject = await channel.object.get();
// Navigate to nested paths and get the instance
-const themeInstance = rootObject.get('settings').get('theme').instance();
+const themeInstance = rootObject.get('settings').get('theme').instance(); // undefined only if nothing exists at the path
// Work directly with the instance
await rootObject.get('visits').instance()?.increment(5);
diff --git a/src/pages/docs/liveobjects/concepts/path-object.mdx b/src/pages/docs/liveobjects/concepts/path-object.mdx
index 597551bf5c..e365f0af64 100644
--- a/src/pages/docs/liveobjects/concepts/path-object.mdx
+++ b/src/pages/docs/liveobjects/concepts/path-object.mdx
@@ -394,7 +394,7 @@ if (settingsInstance != null) {
-If the entry at the path does not exist, or the entry does not contain a `LiveMap` or `LiveCounter` object, `instance()` returns `undefined`:
+`instance()` returns `undefined` only if the entry at the path does not exist. A primitive value is wrapped in a read-only `Instance`:
In the Java SDK, `instance()` returns `null` only if the entry at the path does not exist. A primitive value is wrapped in a read-only primitive instance:
@@ -402,9 +402,15 @@ In the Java SDK, `instance()` returns `null` only if the entry at the path does
```javascript
-// The 'username' entry contains a primitive, not an object
+// The 'username' entry contains a primitive string,
+// so instance() returns a read-only Instance wrapping it
const username = rootObject.get('username').instance();
-console.log(username); // undefined
+console.log(username?.id); // undefined - primitive instances have no object ID
+console.log(username?.value()); // e.g. 'alice'
+
+// instance() returns undefined only when nothing exists at the path
+const missing = rootObject.get('nonexistent').instance();
+console.log(missing); // undefined
```
```java