siyuan-note/siyuan · error
task list item marker can not be [ or ]
Error message
task list item marker can not be [ or ]
What it means
Returned when the single-character `marker` passed to updateTaskListItemMarker is the literal '[' or ']' character. These brackets are the structural delimiters of a GFM task list marker (`[x]`) and are never valid as the status glyph itself, so the kernel rejects them at block_op.go:78 to prevent malformed checkbox rendering.
Source
Thrown at kernel/api/block_op.go:79
return "", errors.New("load tree failed: " + err.Error())
}
li := treenode.GetNodeInTree(tree, id)
if li == nil {
return "", errors.New("block not found")
}
if 3 != li.ListData.Typ {
return "", errors.New("block is not a task list item")
}
if 1 != len(marker) {
return "", errors.New("task list item marker length should be 1")
}
liMarker := marker[0]
if '[' == liMarker || ']' == liMarker {
return "", errors.New("task list item marker can not be [ or ]")
}
markerNode := li.ChildByType(ast.NodeTaskListItemMarker)
if nil == markerNode {
return "", errors.New("task list item marker not found")
}
markerNode.TaskListItemMarker = liMarker
markerNode.TaskListItemChecked = ' ' != markerNode.TaskListItemMarker
treenode.RefreshUpdated(li)
return luteEngine.RenderNodeBlockDOM(li), nil
}
func updateTaskListItemMarker(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)View on GitHub (pinned to 251596fc0d)
Solutions
- Forward the inner status character of the GFM token: marker = gfmToken[1] (the middle char of '[x]').
- Whitelist allowed glyphs before the call: [' ', 'x', 'X'] or your custom set, excluding '[' and ']'.
- If building a UI toggle, send 'x' for on and ' ' (space) for off.
Example fix
// before const marker = gfmToken[0] // yields '[' // after const marker = gfmToken[1] // yields 'x' or ' '
Defensive patterns
Strategy: validation
Validate before calling
function nonBracketMarker(m) {
return m.length === 1 && m !== '[' && m !== ']';
} Type guard
function isSafeMarkerChar(c: unknown): c is string {
return typeof c === 'string' && c.length === 1 && c !== '[' && c !== ']';
} Try / catch
try { await updateTaskMarker(id, marker); }
catch (e) { if (/can not be \[ or \]/.test(e.msg)) { marker = marker === '[' || marker === ']' ? ' ' : marker; await updateTaskMarker(id, marker); } else throw e; } Prevention
- Never derive the marker from index 0 or 2 of a '[x]' token.
- Use a fixed mapping: checked='x', unchecked=' '.
- Unit-test the marker derivation against '[x]', '[ ]', '[X]'.
When it happens
Trigger: POST /api/block/updateTaskListItemMarker with {"marker":"["} or {"marker":"]"}. The check at block_op.go:78 fires after the length check passes (so len==1) but before the marker node is written.
Common situations: A caller that extracts the wrong index from a `[x]`/`[ ]` token (e.g. taking index 0 or 2 instead of index 1). Code that iterates characters of the GFM marker and forwards each one. Misreading the API as accepting the bracket pair.
Related errors
- task list item marker length should be 1
- task list item marker not found
- setting or removing [data-task] attribute is not allowed via
- local storage value for key [%s] must not be empty
- invalid import token
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/859d2e71d3ee0a67.
Report an issue: GitHub.