siyuan-note/siyuan · error
each key requires name and type
Error message
each key requires name and type
What it means
databaseCreateKeySpecs requires every key object to carry a non-blank 'name' and a non-blank 'type' (after trimming whitespace). If either is missing or empty, the tool returns 'each key requires name and type'. These map to the attribute-view key definitions used to build the new database.
Source
Thrown at kernel/mcp/tools/database.go:209
func databaseCreateKeySpecs(value any) (ret []*model.AttributeViewCreateKey, err error) {
if nil == value {
return []*model.AttributeViewCreateKey{}, nil
}
items, ok := value.([]any)
if !ok {
return nil, errors.New("keys must be an array")
}
for _, item := range items {
data, itemOK := item.(map[string]any)
if !itemOK {
return nil, errors.New("each key must be an object")
}
name, _ := data["name"].(string)
keyType, _ := data["type"].(string)
icon, _ := data["icon"].(string)
if "" == strings.TrimSpace(name) || "" == strings.TrimSpace(keyType) {
return nil, errors.New("each key requires name and type")
}
ret = append(ret, &model.AttributeViewCreateKey{Name: name, Type: keyType, Icon: icon})
}
return
}
func databaseSuccess(action string, data any) (CallToolResult, error) {
output := &databaseToolOutput{Action: action, Data: data}
serialized, err := json.Marshal(output)
if nil != err {
return CallToolResult{}, err
}
return CallToolResult{
Content: []ContentItem{{Type: "text", Text: string(serialized)}},
StructuredContent: output,
StructuredContentSet: true,
}, nil
}View on GitHub (pinned to 8641553a1f)
Solutions
- Add both name and type to every key object; valid types include text, number, date, select, mSelect, block, url, email, phone, etc.
- Trim your inputs and ensure neither field is whitespace-only.
- Check for JSON typos such as "Name" vs the lowercase "name" key the parser expects.
- Validate key specs client-side before calling databaseCreate.
Example fix
// before
{ "keys": [ { "name": "Due" } ] }
// after
{ "keys": [ { "name": "Due", "type": "date" } ] } Defensive patterns
Strategy: validation
Validate before calling
function assertKeyRequiredFields(keys) {
for (const k of keys) {
const name = (k.name ?? '').trim();
const type = (k.type ?? '').trim();
if (!name || !type) {
throw new TypeError(`key ${JSON.stringify(k)} requires non-empty name and type`);
}
}
} Type guard
function isCompleteKeySpec(k) { return typeof k.name === 'string' && k.name.trim() !== '' && typeof k.type === 'string' && k.type.trim() !== ''; } Try / catch
try {
await mcp.call("databaseCreate", { name, keys });
} catch (e) {
if (e.message === "each key requires name and type") {
// find the key missing name/type and complete it
}
} Prevention
- Include both name and type on every key; trim whitespace before sending
- Use lowercase argument keys exactly (name, type, icon) — no capitalized variants
- Validate against the key-type enum in the client before calling
When it happens
Trigger: Calling databaseCreate with a key entry like {"name":"Notes"} (no type), {"type":"text"} (no name), or {"name":" ","type":"text"} (whitespace-only).
Common situations: Agents omitting the type when it seems obvious; clients copying specs from an existing database but dropping fields; trailing-space names from copy-paste that then fail after TrimSpace.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- keys must be an array
- each key must be an object
- --av is required
- prev must be a string
- previous key not found in current view: %s
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/d8feaa3ecf5f45af.
Report an issue: GitHub.