Bug Description
encodeDataAttribute from @sanity/core-loader throws an invalid segment error when called with {_key} path segments (e.g. encodeDataAttribute(['sections', {_key: 'abc'}, 'images', {_key: 'xyz'}])). This makes it impossible to use encodeDataAttribute with array items identified by _key, which is the pattern documented in hydrogen-sanity's README.
Root Cause
The issue is in the interaction between studioPathToJsonPath and jsonPathToMappingPath in @sanity/client/csm:
1. studioPathToJsonPath creates placeholder segments with _index: -1:
// @sanity/client/csm - resolveEditInfo.js
function studioPathToJsonPath(path) {
return path.map((segment) => {
// ...
if (segment._key)
return { _key: segment._key, _index: -1 }; // ← placeholder, never resolved
// ...
});
}
When given {_key: 'abc'}, it produces {_key: 'abc', _index: -1}. The -1 is a sentinel value meaning "index unknown", but nothing ever resolves it to the actual array index. The result data is available in the calling encodeDataAttribute function but is never passed to studioPathToJsonPath for key-to-index resolution.
2. jsonPathToMappingPath rejects _index: -1:
function jsonPathToMappingPath(path) {
return path.map((segment) => {
if (typeof segment == "string" || typeof segment == "number")
return segment;
if (segment._index !== -1)
return segment._index;
throw new Error(`invalid segment:${JSON.stringify(segment)}`); // ← throws here
});
}
This function converts path segments to numeric indices for CSM mapping lookup, but when _index is -1, it throws instead of falling back to _key-based resolution.
Steps to Reproduce
import { defineEncodeDataAttribute } from '@sanity/core-loader/encode-data-attribute'
const result = {
sections: [
{ _key: 'abc', _type: 'imageFeature', images: [{ _key: 'xyz', crop: 'square' }] }
]
}
const sourceMap = { /* valid CSM from Sanity API */ }
const studioUrl = 'https://my-studio.sanity.studio'
const encodeDataAttribute = defineEncodeDataAttribute(result, sourceMap, studioUrl)
// This throws: "invalid segment: {"_key":"abc","_index":-1}"
encodeDataAttribute(['sections', { _key: 'abc' }, 'images', { _key: 'xyz' }])
Error
Error: invalid segment:{"_key":"abc123","_index":-1}
at jsonPathToMappingPath (resolveEditInfo.js)
at resolveMapping (resolveEditInfo.js)
at resolveEditInfo (resolveEditInfo.js)
at encodeDataAttribute (encode-data-attribute.js)
Expected Behavior
encodeDataAttribute should resolve {_key} path segments against the result data to determine the actual array index, then use that index for CSM mapping lookup. The result data is already available in the encodeDataAttribute closure but is not used for path resolution.
Suggested Fix
Option A: Resolve _key to _index using the result data in encodeDataAttribute before calling resolveEditInfo:
const encodeDataAttribute = (result, sourceMap, studioUrl, studioPathLike) => {
if (!sourceMap || !studioUrl) return;
const resultPath = studioPathToJsonPath(studioPathLike);
// Resolve _key segments against result data
const resolvedPath = resolveKeySegments(resultPath, result);
const editInfo = resolveEditInfo({ resultPath: resolvedPath, ... });
// ...
};
Option B: Make jsonPathToMappingPath handle _key segments by using _key-based JSON path selectors ([?(@._key=='abc')]) instead of requiring numeric indices, since the CSM may contain either format.
Context
This bug is related to but separate from sanity-io/hydrogen-sanity#185, which tracks a studioUrl serialization issue. Even with studioUrl fixed, encodeDataAttribute fails for {_key} paths due to this bug.
The workaround is to use createDataAttribute from @sanity/core-loader/create-data-attribute instead, which takes explicit document metadata and serializes paths directly without CSM resolution.
Environment
@sanity/client: 7.22.0
@sanity/core-loader: 2.0.9
Bug Description
encodeDataAttributefrom@sanity/core-loaderthrows aninvalid segmenterror when called with{_key}path segments (e.g.encodeDataAttribute(['sections', {_key: 'abc'}, 'images', {_key: 'xyz'}])). This makes it impossible to useencodeDataAttributewith array items identified by_key, which is the pattern documented in hydrogen-sanity's README.Root Cause
The issue is in the interaction between
studioPathToJsonPathandjsonPathToMappingPathin@sanity/client/csm:1.
studioPathToJsonPathcreates placeholder segments with_index: -1:When given
{_key: 'abc'}, it produces{_key: 'abc', _index: -1}. The-1is a sentinel value meaning "index unknown", but nothing ever resolves it to the actual array index. Theresultdata is available in the callingencodeDataAttributefunction but is never passed tostudioPathToJsonPathfor key-to-index resolution.2.
jsonPathToMappingPathrejects_index: -1:This function converts path segments to numeric indices for CSM mapping lookup, but when
_indexis-1, it throws instead of falling back to_key-based resolution.Steps to Reproduce
Error
Expected Behavior
encodeDataAttributeshould resolve{_key}path segments against theresultdata to determine the actual array index, then use that index for CSM mapping lookup. Theresultdata is already available in theencodeDataAttributeclosure but is not used for path resolution.Suggested Fix
Option A: Resolve
_keyto_indexusing the result data inencodeDataAttributebefore callingresolveEditInfo:Option B: Make
jsonPathToMappingPathhandle_keysegments by using_key-based JSON path selectors ([?(@._key=='abc')]) instead of requiring numeric indices, since the CSM may contain either format.Context
This bug is related to but separate from sanity-io/hydrogen-sanity#185, which tracks a
studioUrlserialization issue. Even withstudioUrlfixed,encodeDataAttributefails for{_key}paths due to this bug.The workaround is to use
createDataAttributefrom@sanity/core-loader/create-data-attributeinstead, which takes explicit document metadata and serializes paths directly without CSM resolution.Environment
@sanity/client: 7.22.0@sanity/core-loader: 2.0.9