Without the root id the block is looked for at the top-level1. Something like this seems to work:
useSelect(select => {
const editor = select('core/block-editor')
const rootId = editor.getBlockRootClientId(blockId)
return editor.getBlockIndex(blockId, rootId)
}, [blockId])
[1] https://github.com/WordPress/gutenberg/blob/v9.9.3/packages/block-editor/src/store/selectors.js#L945