nushell/nushell · critical
internal error: missing block
Error message
internal error: missing block
What it means
Panic inside nushell's StateWorkingSet::get_block: a BlockId was passed that is >= the permanent block count but does not index into the working set's delta blocks. Block IDs are assigned as permanent blocks first, then delta blocks appended during the current compile session; a lookup that falls off both ranges means the ID is stale or from a different working set. This is an engine-internal invariant ('internal error') and always indicates a bug in nushell or a misused working set, not bad user input.
Source
Thrown at crates/nu-protocol/src/engine/state_working_set.rs:845
decl_id,
name.to_vec(),
Some(command.description().to_string()),
command.command_type(),
));
});
output
}
pub fn get_block(&self, block_id: BlockId) -> &Arc<Block> {
let num_permanent_blocks = self.permanent_state.num_blocks();
if block_id.get() < num_permanent_blocks {
self.permanent_state.get_block(block_id)
} else {
self.delta
.blocks
.get(block_id.get() - num_permanent_blocks)
.expect("internal error: missing block")
}
}
pub fn get_module(&self, module_id: ModuleId) -> &Module {
let num_permanent_modules = self.permanent_state.num_modules();
if module_id.get() < num_permanent_modules {
self.permanent_state.get_module(module_id)
} else {
self.delta
.modules
.get(module_id.get() - num_permanent_modules)
.expect("internal error: missing module")
}
}
pub fn get_block_mut(&mut self, block_id: BlockId) -> &mut Block {
let num_permanent_blocks = self.permanent_state.num_blocks();
if block_id.get() < num_permanent_blocks {View on GitHub (pinned to 2af17cd99e)
Solutions
- If you hit this as a user, update nushell and file the reproducing script — the message literally says 'internal error', user code cannot trigger it through valid input
- If embedding nushell, always re-resolve BlockIds in the same StateWorkingSet that created them; never reuse IDs after EngineState::merge_delta
- Check bounds before lookup: block_id.get() < permanent_state.num_blocks() + delta.blocks.len()
- As a maintainer, replace expect with a proper ShellError (or debug_assert + fallback) so the engine reports the bad ID instead of panicking
Example fix
// before (parser/embedder code holding a stale id) let block = working_set.get_block(old_block_id); // after: re-resolve the block in the working set that owns it let block_id = working_set.add_block(block); let block = working_set.get_block(block_id);
Defensive patterns
Strategy: validation
Validate before calling
fn block_in_range(ws: &StateWorkingSet, id: BlockId) -> bool {
let n = ws.permanent_state.num_blocks() + ws.delta.blocks.len();
id.get() < n
} Type guard
fn owns_block_id(ws: &StateWorkingSet, id: BlockId) -> bool {
id.get() >= ws.permanent_state.num_blocks()
&& id.get() - ws.permanent_state.num_blocks() < ws.delta.blocks.len()
|| id.get() < ws.permanent_state.num_blocks()
} Prevention
- Never cache BlockIds across EngineState::merge_delta calls; re-resolve after merges
- Only use IDs minted by the same StateWorkingSet that performs the lookup
- In embedded usage, wrap engine calls so unexpected panics surface as reportable bugs rather than crashes
When it happens
Trigger: Calling get_block with a BlockId captured before a merge_delta/reset (IDs shift when the delta is merged and the delta list empties), or using an ID obtained from a different EngineState/StateWorkingSet instance; also any parser code path that computes a BlockId without going through add_block.
Common situations: Contributing parser/evaluator changes to nushell that cache DeclId/BlockId across working-set lifetimes, plugins or embedders that hold engine IDs while the engine state advances, or a refactor that reorders block registration during compile.
Related errors
- internal error: missing module
- internal error: missing added overlay
- internal error: missing virtual path
- must be OK
- we guarantee that 1 entry is always in a list
AI-assisted analysis of nushell/nushell@2af17cd99e (2026-08-17).
Data as JSON: /api/errors/397f34e7d32c4c0e.
Report an issue: GitHub.