siyuan-note/siyuan · error
unsupported block operation
Error message
unsupported block operation [%s]
What it means
PerformBlockOperation returns "unsupported block operation [%s]" when the operation's Action falls into the default case of its switch — i.e. an action name the kernel does not implement. Only explicitly supported actions (such as "delete") reach the transaction stage.
Solutions
- Use exactly the supported action name (e.g. "delete" — lowercase, no variants).
- Check the server's API docs / handler source for the list of supported actions for your kernel version.
- Update the plugin/API client if it targets a different SiYuan version's action set.
- Validate the action string against a whitelist before sending.
Example fix
// before
await fetchPost('/api/block/performBlockOperation', { operations: [{ action: 'remove', id }] });
// after
await fetchPost('/api/block/performBlockOperation', { operations: [{ action: 'delete', id }] }); Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED_ACTIONS = ['delete'];
function assertSupportedAction(action) {
if (!SUPPORTED_ACTIONS.includes(action)) throw new Error(`unsupported action: ${action}`);
} Try / catch
try { await performBlockOperation(action, id); } catch (e) { if (String(e.msg).includes('unsupported block operation')) console.error(`bad action '${action}'; see API docs for supported values`); throw e; } Prevention
- Keep an explicit whitelist of supported action strings in client code.
- Pin plugin code to a documented SiYuan kernel version and re-check actions on upgrade.
- Use exact lowercase action names from docs/API.md.
When it happens
Trigger: Passing an Action string that is not one of the supported values to the block operation API — typos like "Delete", "remove", or actions copied from another API's vocabulary.
Common situations: Plugin/API clients written against a newer or different API spec; hand-written automation scripts guessing action names; version drift where a client expects an action this kernel build does not support.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- block updates are empty
- document cannot be deleted as a block
- invalid appearance mode
- response.msg
- Source content is only supported for template preview
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/9461f7bb6c78ea4d.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/block_operation.go:52
if err = treenode.CheckContainerParent(operation.ParentID); err != nil {
return nil, err
}
}
case "delete":
// 外部删除请求必须命中现存节点,编辑器内部仍可使用幂等删除。
tree, loadErr := LoadTreeByBlockID(operation.ID)
if loadErr != nil {
return nil, loadErr
}
node := treenode.GetNodeInTree(tree, operation.ID)
if node == nil {
return nil, fmt.Errorf("block not found [%s]", operation.ID)
}
if node == tree.Root {
return nil, fmt.Errorf("document cannot be deleted as a block [%s]", operation.ID)
}
default:
return nil, fmt.Errorf("unsupported block operation [%s]", operation.Action)
}
tx := &Transaction{DoOperations: []*Operation{operation}}
if err = performTxSyncLocked(tx); err != nil {
return nil, err
}
return []*Transaction{tx}, nil
}
View on GitHub (pinned to 9f775e8a12)