{"record":{"id":"dc9e6edd4755d3b9","repo":"siyuan-note/siyuan","slug":"cannot-create-a-file-starting-with","errorCode":null,"errorMessage":"Cannot create a file starting with .","messagePattern":"Cannot create a file starting with \\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/file.go","lineNumber":2328,"sourceCode":"\tif 512 < utf8.RuneCountInString(title) {\n\t\t// 限制笔记本名和文档名最大长度为 `512` https://github.com/siyuan-note/siyuan/issues/6299\n\t\treturn nil, errors.New(Conf.Language(106))\n\t}\n\n\tisEmpty := false\n\tif \"\" == title {\n\t\ttitle = Conf.Language(16)\n\t\tisEmpty = true\n\t} else if titleEmpty {\n\t\tisEmpty = true\n\t}\n\n\tbaseName := strings.TrimSpace(path.Base(p))\n\tif \"\" == util.GetTreeID(baseName) {\n\t\treturn nil, errors.New(Conf.Language(16))\n\t}\n\tif strings.HasPrefix(baseName, \".\") {\n\t\treturn nil, errors.New(Conf.Language(13))\n\t}\n\n\tbox, boxErr := getOpenedBox(boxID)\n\tif nil != boxErr {\n\t\treturn nil, boxErr\n\t}\n\n\tfolder := path.Dir(p)\n\thPath := \"/\" + title\n\tif \"/\" != folder {\n\t\tparentID := path.Base(folder)\n\t\tparentTree, loadErr := LoadTreeByBlockID(parentID)\n\t\tif nil != loadErr {\n\t\t\tlogging.LogErrorf(\"get parent tree [%s] failed\", parentID)\n\t\t\treturn nil, ErrBlockNotFound\n\t\t}\n\t\tparentPath := strings.TrimSuffix(parentTree.Path, \".sy\")\n\t\tif parentTree.Box != boxID || cleanBoxDocDir(parentPath) != cleanBoxDocDir(folder) {","sourceCodeStart":2310,"sourceCodeEnd":2346,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/file.go#L2310-L2346","documentation":"The very next guard in validateCreateDoc (kernel/model/file.go:2328): after the basename yields a valid tree ID, it must not start with '.' — dot-prefixed files are hidden/config files in the notebook directory (like .siyuan/), so creating a document named \".<something>.sy\" is rejected with Conf.Language(13) (\"Cannot create a file starting with .\").","triggerScenarios":"POST /api/filetree/createDoc / createDocWithMd with path whose filename component begins with a dot, e.g. \"/.draft-20240101......sy\" or \"/parent/.20240101120000-abcd123.sy\" (the ID passed the previous check but the leading dot fails this one).","commonSituations":"Unix-minded users naming files .draft.sy; sanitizers that prefix temp names with '.'; importers preserving dotfiles found in a source folder.","solutions":["Remove the leading dot from the filename: use \"20240101120000-abcd123.sy\" style names","Sanitize external filenames in import pipelines (strip leading dots before building the create path)","Keep hidden-file conventions out of data/<box>/ — the kernel reserves dot-entries for its own metadata"],"exampleFix":"// before\nfetchPost('/api/filetree/createDocWithMd', {notebook, path: `/.${id}.sy`, markdown})\n\n// after\nfetchPost('/api/filetree/createDocWithMd', {notebook, path: `/${id}.sy`, markdown})","handlingStrategy":"validation","validationCode":"base := strings.TrimSpace(path.Base(p))\nif strings.HasPrefix(base, \".\") {\n\treturn fmt.Errorf(\"document filename must not start with '.': %s\", base)\n}","typeGuard":"func hasNoLeadingDot(p string) bool { return !strings.HasPrefix(strings.TrimSpace(path.Base(p)), \".\") }","tryCatchPattern":null,"preventionTips":["Strip leading dots during import sanitization, before path construction","Reserve dot-prefixed entries for kernel metadata (.siyuan/ etc.) in data/<box>/","Combine this check with the tree-ID check in one path validator"],"tags":["siyuan","create-doc","filename","hidden-file","validation"],"backgroundTag":"invalid-filename-rejected","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}